Ms word 使用documentformat.openxml从具有多个页面的word模板创建新文档

Ms word 使用documentformat.openxml从具有多个页面的word模板创建新文档,ms-word,openxml,openxml-sdk,Ms Word,Openxml,Openxml Sdk,我有一个带有一些内容控件的Microsoft Word模板。它包含一个目录和一些额外的信息 在该页面上,我设置了一些内容控件,希望在其中插入来自RESTful服务的新文本。如果RESTful服务返回一个数据(对象)数组,我需要根据Word模板复制每个页面上的信息 关于如何使用OpenXMLSDK(DocumentFormat.OpenXml)实现这一点,您有什么想法吗 编辑: 我在这里发现了这个,这很好,但我不知道如何将数据数组应用于同一模板中的多个页面 那么,如何在新文档中从同一模板创建多个页

我有一个带有一些内容控件的Microsoft Word模板。它包含一个目录和一些额外的信息

在该页面上,我设置了一些内容控件,希望在其中插入来自RESTful服务的新文本。如果RESTful服务返回一个数据(对象)数组,我需要根据Word模板复制每个页面上的信息

关于如何使用OpenXMLSDK(
DocumentFormat.OpenXml
)实现这一点,您有什么想法吗

编辑:

我在这里发现了这个,这很好,但我不知道如何将数据数组应用于同一模板中的多个页面

那么,如何在新文档中从同一模板创建多个页面?数据以数组的形式出现。

下面的示例代码(经过单元测试并有效)实现了您想要实现的目标。它基于对问题和假设的以下解释:

  • “控件占位符”是指“富文本内容控件”,在开放XML行话中称为块级结构化文档标记(SDT),因此由开放XML SDK中的
    SdtBlock
    类表示
  • 内容控件具有标记,这意味着相关的
    w:sdt
    元素具有孙子元素,如
    。这些标记用于将从REST服务接收的数据链接到内容控件
  • 数据作为
    字典提供
    ,将标记值映射到内容控制文本(数据)
一般的方法是对
WordprocessingDocument
的主文档部分执行纯功能转换。
void WriteContentControls(WordprocessingDocument)
方法包装最外层的纯函数转换
对象转换文档(OpenXmlElement)
。后者使用内部纯函数转换
对象转换dtblock(openxmlement,string)

公共类ContentControlWriter
{
私有只读IDictionary\u contentMap;
/// 
///初始化新的ContentControlWriter实例。
/// 
///内容控制标签到内容控制文本的映射。
/// 
公共ContentControlWriter(IDictionary contentMap)
{
_contentMap=contentMap;
}
/// 
///通过设置内容转换给定的WordprocessingDocument
///相关块级内容控件的名称。
/// 
///要转换的WordprocessingDocument。
公共无效WriteContentControls(WordprocessingDocument wordDocument)
{
MainDocumentPart=wordDocument.MainDocumentPart;
part.Document=(Document)TransformDocument(part.Document);
}
私有对象转换文档(OpenXmlElement)
{
if(元件为SdtBlock sdt)
{
字符串tagValue=GetTagValue(sdt);
if(_contentMap.TryGetValue(tagValue,输出字符串文本))
{
返回TransformSdtBlock(sdt,文本);
}
}
返回转换(元素、转换文档);
}
私有静态对象TransformSdtBlock(OpenXmlElement元素,字符串文本)
{
返回元素是SdtContentBlock
?新SdtContentBlock(新段落(新运行)(新文本(文本)))
:Transform(element,e=>TransformSdtBlock(e,text));
}
私有静态字符串GetTagValue(SdtElement sdt)=>sdt
.后代()
.Select(tag=>tag.Val.Value)
.FirstOrDefault();
私有静态T变换(T元素,Func变换)
其中T:openxmlement
{
var transformedElement=(T)element.CloneNode(false);
Append(element.Elements().Select(e=>(openxmlement)transformation(e));
返回转换元素;
}
}
即使细节不同(例如,关于如何将数据数组映射到特定内容控件),这也应该为实现特定解决方案提供足够的输入。此外,如果不使用块级结构化文档标记(
SdtBlock
,富文本内容控件),而是使用内联级结构化文档标记(
SdtRun
,纯文本内容控件),则原理相同。与包含在
SdtContentBlock
实例中的
段落
实例(
w:p
元素)不同,您将拥有包含在
SdtContentRun
实例中的
Run
实例(
w:r
元素)


更新2019-11-23:My GitHub存储库包含和类的代码。后者显示了如何使用
ContentControlWriter
类。

感谢Thomas的反馈。我会给你的代码一个尝试,希望我能解决它。我将在继续过程中提供更多信息。@BurreIfort,有关如何使用
ContentControlWriter
的问题,请参阅我对您的另一个问题的回答。我已更新了我的回答,以包含指向我的代码片段GitHub存储库中包含的完整代码示例的链接。