简体   繁体   中英

How to “Insert text from file” using OpenXml SDK 2.0

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?

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;
}

It is not as simple as inserting the descendants of the document body tag at the bookmark location. Some reasons:

  • The two documents may be using different styles; you would have to copy across dependant styles, or update the references to use the styles in the destination document.
  • The <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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM