I am fairly new to using DocumentBuilder and I am putting together a solution that consumes an xml document (which contains paths to docx files). The solution is intended to assemble a number of docx files into one resultant file.
When using the WmlDocument object that is returned from DocumentBuilder.BuildDocument(sources) how do I get a WordProcessingDocument object from the WmlDocument object?
I need the WordProcessingDocument object so that I can interrogate and modify the document parts and then stream the final result back to the client caller.
If my question is not clear I can provide more detail.
Thanks
After a few more minutes of digging I solved my own problem.
The answer is to create an OpenXmlMemoryStreamObject and pass the WmlDocument into the constructor. I then used the GetWordProcessingDocument() method to return the WordProcessingDocument, made some changes to the document and then created a new source using the GetModifiedWmlDocument() method. Something like:
List<Source> mainSourceList = new List<Source>(); WmlDocument wmlDoc = DocumentBuilder.BuildDocument(sources); WmlDocument clonedDoc = null; OpenXmlMemoryStreamDocument streamDoc = null; foreach (XElement recipient in recipientList) { clonedDoc = new WmlDocument(wmlDoc); streamDoc = new OpenXmlMemoryStreamDocument(clonedDoc); .... WordprocessingDocument wpd = streamDoc.GetWordprocessingDocument(); Paragraph p = new Paragraph(new Run(new Break() {Type = BreakValues.Page})); wpd.MainDocumentPart.Document.Body.Append(p); wpd.MainDocumentPart.Document.Save(); mainSourceList.Add(new Source(streamDoc.GetModifiedWmlDocument(), true)); } WmlDocument finalDocument = DocumentBuilder.BuildDocument(mainSourceList);
That is the general idea behind those classes, but it is better to create them in "using" statements like this example from the Markup Simplifier:
public static WmlDocument SimplifyMarkup(WmlDocument doc, SimplifyMarkupSettings settings) { using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc)) { using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument()) { SimplifyMarkup(document, settings); } return streamDoc.GetModifiedWmlDocument(); } }
It can be important for the WordprocessingDocument object to be disposed before calling GetModifiedWmlDocument. Then it is important that the OpenXmlMemoryStream object be disposed. The issues I have discovered may not come up in your example, but this arrangement is the best.