Inserting text after a bookmark in openxml

后端 未结 2 1796
被撕碎了的回忆
被撕碎了的回忆 2021-02-09 00:00

I am looking for a way to insert some text after a bookmark in a word doc using openxml. So far, i have been able to locate the bookmark using the following:

var         


        
相关标签:
2条回答
  • 2021-02-09 00:39

    You can not assume that a bookmark starts and ends in one paragraph. Bookmarks can start and end in different elements and be children of:

    bdo (§17.3.2.3); body (§17.2.2); comment (§17.13.4.2); customXml (§17.5.1.6); customXml (§17.5.1.4); customXml (§17.5.1.5); customXml (§17.5.1.3); deg (§22.1.2.26); del (§17.13.5.14); den (§22.1.2.28); dir (§17.3.2.8); docPartBody (§17.12.6); e (§22.1.2.32); endnote (§17.11.2); fldSimple (§17.16.19); fName (§22.1.2.37); footnote (§17.11.10); ftr (§17.10.3); hdr (§17.10.4); hyperlink (§17.16.22); ins (§17.13.5.18); lim (§22.1.2.52); moveFrom (§17.13.5.22); moveTo (§17.13.5.25); num (§22.1.2.75); oMath (§22.1.2.77); p (§17.3.1.22); rt (§17.3.3.24); rubyBase (§17.3.3.27); sdtContent (§17.5.2.34); sdtContent (§17.5.2.33); sdtContent (§17.5.2.35); sdtContent (§17.5.2.36); smartTag (§17.5.1.9); sub (§22.1.2.112); sup (§22.1.2.114); tbl (§17.4.38); tc (§17.4.66); tr (§17.4.79)

    https://msdn.microsoft.com/en-gb/library/documentformat.openxml.wordprocessing.bookmarkstart(v=office.15).aspx

    This means you need to look at all the BookmarkEnd elements in the document when checking for the required BookmarkEnd element.

    Body body = mainPart.Document.GetFirstChild<Body>();
    var bookMarkStarts = body.Descendants<BookmarkStart>();
    var bookMarkEnds = body.Descendants<BookmarkEnd>();
    
    foreach (BookmarkStart bookMarkStart in bookMarkStarts)
    {
        if (bookMarkStart.Name == bookmarkName)
        {
            //Get the id of the bookmark start to find the bookmark end
            var id = bookMarkStart.Id.Value;
            var bookmarkEnd = bookMarkEnds.Where(i => i.Id.Value == id).First();
    
            var runElement = new Run(new Text("Hello World!!!"));
    
            bookmarkEnd.Parent.InsertAfter(runElement, bookmarkEnd);
        }
    }
    mainPart.Document.Save();
    

    You may want to check that a Run can be added to the parent and add to a different ancestor or create a new Paragraph.

    (I would have liked to have added this as a comment to Flowerking's answer but I can't comment so I have modified their code in this answer.)

    0 讨论(0)
  • 2021-02-09 00:50

    using

    bookMarkToWriteAfter.Parent.InsertAfterSelf(run);
    

    you are trying to work with XML directly which is not always advisable with OpenXML.

    Try This..

        Body body = mainPart.Document.GetFirstChild<Body>();
        var paras = body.Elements<Paragraph>();
    
        //Iterate through the paragraphs to find the bookmarks inside
        foreach (var para in paras)
        {
            var bookMarkStarts = para.Elements<BookmarkStart>();
            var bookMarkEnds = para.Elements<BookmarkEnd>();
    
    
            foreach (BookmarkStart bookMarkStart in bookMarkStarts)
            {
                if (bookMarkStart.Name == bookmarkName)
                {
                    //Get the id of the bookmark start to find the bookmark end
                    var id = bookMarkStart.Id.Value;
                    var bookmarkEnd = bookMarkEnds.Where(i => i.Id.Value == id).First();
    
                    var runElement = new Run(new Text("Hello World!!!"));
    
                    para.InsertAfter(runElement, bookmarkEnd);
    
                }
            }
       }
       mainPart.Document.Save();
    
    0 讨论(0)
提交回复
热议问题