0

I am looking for alternatives to using openxml for a server-side word automation project. Does anyone know any other ways that have features to let me manipulate word bookmarks and tables?

John Baum
  • 3,183
  • 11
  • 42
  • 90
  • What are you trying to automate and why does openxml not fit your needs, without those details it will be difficult to provide other options. – Scott Chamberlain Mar 22 '12 at 14:17
  • i am trying to delete all the text within a bookmark start and bookmarkend. openxml doesnt let me do this as far as i know – John Baum Mar 22 '12 at 14:22
  • Now knowing what you want to do see this question it is basically the same thing you want to do. http://stackoverflow.com/questions/3308299/replace-bookmark-text-in-word-file-using-open-xml-sdk – Scott Chamberlain Mar 22 '12 at 14:34
  • @JohnBaum you should have mentioned this in the question itself.. – Flowerking Mar 22 '12 at 14:34
  • that method does not work for me. The next sibling after my bookmark is not the only element part of the actual bookmark in the doc. – John Baum Mar 22 '12 at 14:35

1 Answers1

1

I am currently doing a project of developing a word automation project for my company and I am using DocX Very simple and straight forward API to work with. The approach I am using is, whenever I need to work with XML directly, this API has a property named "xml" in the Paragraph class which gives you access to the underlying xml direclty so that I can work with it. The best part is its not breaking the xml and not corrupting the resulting document. Hope this helps!

Example code using DocX..

 XNamespace ns = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
    using(DocX doc = DocX.Load(@"c:\temp\yourdoc.docx"))
    {
         foreach( Paragraph para in doc.Paragraphs )
         {
             if(para.Xml.ToString().Contains("w:Bookmark"))
             {
                 if(para.Xml.Element(ns + "BookmarkStart").Attribute("Name").Value == "yourbookmarkname")
                  {
                          // you got to your bookmark, if you want to change the text..then 
                          para.Xml.Elements(ns + "t").FirstOrDefault().SetValue("Text to replace..");
                  }
             }
         }
    }

Alternative API exclusively to work with bookmarks is .. http://simpleooxml.codeplex.com/

Example on how to delete text from bookmarkstart to bookmarkend using this API..

 MemoryStream stream = DocumentReader.Copy(string.Format("{0}\\template.docx", TestContext.TestDeploymentDir));
 WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);
 MainDocumentPart mainPart = doc.MainDocumentPart;

 DocumentWriter writer = new DocumentWriter(mainPart);

 //Simply Clears all text between bookmarkstart and end
 writer.PasteText("", "YourBookMarkName");


 //Save to the memory stream, and then to a file
 writer.Save();

 DocumentWriter.StreamToFile(string.Format("{0}\\templatetest.docx", GetOutputFolder()), stream);

Loading the word document into different API's from memory stream.

//Loading a document file into memorystream using SimpleOOXML API
MemoryStream stream = DocumentReader.Copy(@"c\template.docx");

//Opening it from the memory stream as OpenXML document
WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);

//Opening it as DocX document for working with DocX Api
DocX document = DocX.Load(stream); 
Flowerking
  • 2,551
  • 1
  • 20
  • 30
  • am i able to access the bookmarks in the word doc using docX? – John Baum Mar 22 '12 at 13:31
  • not out of the box.. but you can get hold of it from the underlying xml directly..depending on your requirement.. – Flowerking Mar 22 '12 at 13:40
  • can you give an example on how i can use the xml to get at the bookmarks – John Baum Mar 22 '12 at 13:48
  • Does this api support finding a bookmark and writing some text directly following it? THats another one of the things i need to accomplish – John Baum Mar 22 '12 at 14:38
  • thats what PasteText method is doing.. writer.PasteText("write some text", "yourBookMarkName"); .. as simple as that.. – Flowerking Mar 22 '12 at 14:41
  • ok, my bookmark is a selection of 3 lines. Based on some criteria i have to either erase all the bookmark selection of lines or enter a new line after the bookmark and write a table there. Which of these two tasks does parse text accomplish? – John Baum Mar 22 '12 at 14:42
  • You can use it to erase all the lines spanning that bookmark using PasteText method, and its easy to use OpenXml to instert a table isn't it? – Flowerking Mar 22 '12 at 14:45
  • well i was trying to avoid having to use two different api's and have one single solution. – John Baum Mar 22 '12 at 14:48
  • if i use two seperate apis, i have difficulty saving as openxml opens the file and docx also opens the file but both cant save to it – John Baum Mar 22 '12 at 16:24
  • yes..I agree. that is a potential problem unless you work with memory streams or save and open the same file within the program separately for achieving different functionality.. – Flowerking Mar 22 '12 at 16:32
  • Both the api's mentioned above support loading directly from a stream, so i think its easy to work with them by passing the document as a memory stream between methods.. – Flowerking Mar 22 '12 at 16:37
  • i actually cant get access to the memory stream and docwriter for the docx api. Is there something i have to iport? – John Baum Mar 22 '12 at 20:06
  • Thanks for updating the answer. One thing that i still cant get to work is the documentreader. It cant find that reference and i dont know how to get visual studio to recognize it? – John Baum Mar 23 '12 at 13:28
  • DocumentReader is class from SimpleOOXML APi, did you reference it properly in your solution? – Flowerking Mar 23 '12 at 13:44
  • I want to use just the docx api. How can i get access to the document reader/writer? – John Baum Mar 23 '12 at 13:48
  • DocumentReader is a helper class in SimpleOOXML api to help loading the document, you don't need it with DocX API, you can just load the document like - DocX.Load(@"c:\yourdoc.docx"); – Flowerking Mar 23 '12 at 13:50
  • Oh.. But thats just a normal stream object, you can just use FileStream from System.IO to do that .. like - FileStream stream = new FileStream(@"c:\yourdoc.docx", FileMode.Open); – Flowerking Mar 23 '12 at 13:56
  • i tried this approach just now to replace the bookmark text and it didnt appear to do anything. Did it work in your test? – John Baum Mar 23 '12 at 14:04
  • Yes.. did you also try SimpleOOXMl, as it is more specific to working with bookmarks, did you try using the PasteText Method in it...its working exactly how you are intending to do with your case.. – Flowerking Mar 23 '12 at 14:06
  • yes i am using the simpleooxml and the pastetext method. It doesnt seem to find the bookmark when i enter the bookmarkname. It says "Sequence contains no elements" – John Baum Mar 23 '12 at 14:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/9234/discussion-between-john-baum-and-flowerking) – John Baum Mar 23 '12 at 14:31
  • the bookmark deletion works now. The inserting a table at a specific point however does not. – John Baum Mar 26 '12 at 15:58
  • Try commenting out these two line - in CleanNodes() method - var start = _doc.Xml.Descendants(ns + "bookmarkStart").ToList(); var end = _doc.Xml.Descendants(ns + "bookmarkEnd").ToList(); – Flowerking Mar 26 '12 at 15:59
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/9328/discussion-between-john-baum-and-flowerking) – John Baum Mar 26 '12 at 16:03
  • I leave the office by 5 (GMT) and that's when u r free :( I guess the code is just working fine and is a bit noddy and most straight forward to what u r looking for. Just refactor it to your needs. All the best..Cheers :) – Flowerking Mar 28 '12 at 08:30