Reputation: 723
Using Word 2010 GUI, there is an option to "Insert text from file...", which does exactly that: It insert the text in the main part of a document to the current location in your document.
I would like to do the same using C# and the OpenXml SDK 2.0
using (var mainDocument = WordprocessingDocument.Open("MainFile.docx", true);
{
var mainPart = mainDocument.MainDocumentPart;
var bookmarkStart = mainPart
.Document
.Body
.Descendants<BookmarkStart>()
.SingleOrDefault(b => b.Name == "ExtraContentBookmark");
var extraContent = GetTextFromFile("ExtraFile.docx");
bookmarkStart.InsertAfterSelf(extraContent);
}
I have tried using plain Xml (XElement), using OpenXmlElement (MainDocumentPart.Document.Body.Descendants), and using AltChunk. Every alternative so far has yielded a non-conformant docx-file.
What should the method GetTextFromFile
look like?
Upvotes: 2
Views: 2503
Reputation: 723
This is how I implemented it. The solution was to use AltChunk as described by Eric White. I had already tried it, but as Bradley said in his answer, a bookmark may be anywhere in a document, and mine was inside a paragraph. As soon as I inserted the text before the containing paragraph, everything worked fine.
Here is the (simplified) code:
using (var mainDocument = WordprocessingDocument.Open("MainFile.docx", true);
{
var mainPart = mainDocument.MainDocumentPart;
var bookmarkStart = mainPart
.Document
.Body
.Descendants<BookmarkStart>()
.SingleOrDefault(b => b.Name == "ExtraContentBookmark");
var altChunk = GetAltChunkFromFile("ExtraFile.docx", mainPart);
var containingParagraph = element.Ancestors<Paragraph>().FirstOrDefault();
containingParagraph.InsertBeforeSelf(altChunk);
}
...
private AltChunk GetAltChunk(string filename, MainDocumentPart mainDocumentPart)
{
var altChunkId = "AltChunkId1";
var chunk = mainDocumentPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkId);
chunk.FeedData(File.Open(filename, FileMode.Open));
var altChunk = new AltChunk { Id = altChunkId };
return altChunk;
}
Upvotes: 2
Reputation: 13621
It is not as simple as inserting the descendants of the document body tag at the bookmark location. Some reasons:
<bookmarkStart>
tag can appear almost anywhere in a document, including inside a paragraph, a run, a table cell, etc. Since you cannot nest paragraphs or runs, you will have to determine where the bookmark is situated, then ascend/descend the XML tree until you find an appropriate place to insert the content.What you're trying to do becomes quite a complicated task when using the OpenXml SDK. It requires an in-depth understanding of the format and its schema.
I would almost advise using VSTO/OLE automation instead, as it enables you to use the functionality that is built into Word.
Upvotes: 1