在 Word 内容控件中注入一些带有富文本的段落的正确方法是什么?

What is the correct way to inject some paragraphs with rich text in a Word content control?

我正在尝试使用 Open Xml SDK 在 Word 内容控件中插入一些段落。

我的代码似乎有效(段落在 word 文件中可见)。但是,无法编辑控制控件。在插入新内容之前,我只能删除所有内容。

如何将手册copy/paste模仿成内容控件?

仅供参考,这是我的代码:

var mainPart = package.MainDocumentPart;

var sdtRuns = mainPart.Document.Descendants<SdtElement>().Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == "TagOfMyContentControl");

foreach (var sdtBlock in sdtRuns)
{
    List<Paragraphs> paragraphs = GetParapraphsFromSomewhere();
    var contentControlParagraph = sdtBlock.Descendants<SdtContentBlock>().First();
    contentControlParagraph.RemoveAllChildren();
    contentControlParagraph.Append(paragraphs);
}

mainPart.Document.Save();

PS:我是一个更通用的方法,是否有任何资源可以解释 Word ML 元素的用途和层次结构?

您的代码类似于将复制粘贴复制到内容控件中。以下两行是删除内容控件中所有段落的行:

var contentControlParagraph = sdtBlock.Descendants<SdtContentBlock>().First();
contentControlParagraph.RemoveAllChildren();

相反,您需要确定要放置段落的位置,然后 Append 将其放在那里。

例如,我有一个名为CopyPasteCC 的富文本内容控件的docx。此图像显示开发人员模式下的文档。内容控件有 3 个现有段落。

然后,我将您的代码替换为以下内容:

        var mainPart = document.MainDocumentPart;

        var sdtRuns = mainPart.Document.Descendants<SdtElement>().Where(run => run.SdtProperties.GetFirstChild<Tag>().Val.Value == "CopyPasteCC");

        sdtRuns.ElementAt(0).Descendants<Paragraph>().ElementAt(1).InsertAfterSelf(
            new Paragraph(new Run(new Text("Hello - this is new Copy Paste paragraph")))
            );

        mainPart.Document.Save();

第三行选择第二行内容控件中的所有段落。然后它在第二个现有段落之后插入一个新段落。下图是上面这段代码有运行:

后的文件

回答您的 PS 问题 - 有正式的 OpenXML Specification you can try to read. This is not easy reading, but it is the authoritative specification. There is a more general (but dated) free e-book titled OpenXml Explained

我每个月参考一次这些以获取信息。 OpenXml Explained 的第一章涵盖了 WordprocessingML,在第 39 页上有一个关于结构化文档标签的部分,其中概述了内容控件。