在openxml中的书签后插入文本

时间:2012-03-19 16:36:52

标签: c# ms-word openxml word-automation

我正在寻找一种方法,使用openxml在word doc中的书签后插入一些文本。到目前为止,我已经能够使用以下内容找到书签:

var bookmarks = mainPart.Document.Descendants<BookmarkStart>().ToList();
var bookMarkToWriteAfter = bookmarks.FirstOrDefault(bm => bm.Name == insertAfterBoomark.Name);

单词doc中的这个书签是doc中两行的选择。我必须在两行选择后立即插入一些文本。我试图使用以下内容插入文本:

var run = new Run();
run.Append(new Text("Hello World"));
bookMarkToWriteAfter .Parent.InsertAfterSelf(run);

mainPart.Document.Save();
然而,这不会产生所需的结果。有没有人知道使用openxml在word文档中的书签后插入文本的正确方法?

2 个答案:

答案 0 :(得分:8)

使用

bookMarkToWriteAfter.Parent.InsertAfterSelf(run);

您正在尝试直接使用XML,这对于OpenXML并不总是可取的。

试试这个..

    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();

答案 1 :(得分:2)

您不能假设书签以一个段落开头和结尾。书签可以在不同的元素中开始和结束,并且是以下的孩子:

bdo(§17.3.2.3);身体(第17.2.2节);评论(§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);尾注(§17.11.2); fldSimple(§17.16.19); fName(§22.1.2.37);脚注(§17.11.10); ftr(§17.10.3); hdr(§17.10.4);超链接(§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

这意味着在检查所需的BookmarkEnd元素时,您需要查看文档中的所有BookmarkEnd元素。

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();

您可能需要检查是否可以将“运行”添加到父级并添加到其他祖先或创建新的段落。

(我本来希望将此添加为对Flowerking的回答的评论,但我无法发表评论,所以我在这个答案中修改了他们的代码。)