使用XML文件中的数据生成Word文档(docx)/基于模板将XML转换为Word文档

问题描述:

我有一个XML文件,其中包含需要在Word文档中填充的数据.

I have an XML file with the data that I need to be populated on a Word document.

我需要找到一种方法来定义一个模板,该模板可以用作从XML文件填充数据并创建输出文档的基线.

I need to find a way, to define a template which can be used as a base line to populate data from an XML file and create an output document.

我相信有两种方法可以做到这一点.

I believe there are two ways to do this.

  1. 创建一个XSLT文件,它将作为模板",并使用它与XML文件结合使用以生成Word文档.
  2. 使用Word中的内容控件创建模板文档,并以某种方式映射到XML文件.

我只是不知道如何实现任何一种方式的细节.还是不确定是否还有另一种更简单的方法来完成此任务.

I just don't know the details on how to implement either way. Or not sure if there is another, easier way to accomplish this task.

有人可以举例说明如何实现这一点.一个简单的例子就足够了.

Could someone show an example of how this can be implemented. Just a simple example would be sufficient.

我更喜欢C#进行任何编码.我正在使用Word 2016,但希望它与Word 2007到Word 2016以及两者之间的所有内容兼容(如果可能的话),因为用户将使用这些版本.谢谢!

I prefer C# for any coding. I am using Word 2016 but want it to be compatible from Word 2007 to Word 2016 and everything in between if possible since users will be using these versions. Thank you!

了解了如何使用内容控件生成文档以及如何将XML中的数据填充到内容控件中.我将其分为两部分:

Figured out how to use content controls to generate documents and how to populate data from an XML into content controls. I've divided this into 2 parts:

  • 第1部分:创建用于文档生成的模板文档
  • 第2部分:使用C#中的代码基于模板生成文档
  1. 创建一个示例XML,您可以基于该XML创建用于文档生成的Word模板.最好从不太复杂的版本入手.

我使用以下XML进行测试.为了进行测试,我没有重复的部分,图片等.

I used the following XML for testing. For testing I didn't have repeating sections, pictures etc.

<?xml version="1.0" encoding="utf-8"?>
<mydata xmlns="http://CustomDemoXML.htm">
    <field1>This is the value in field1 from the XML file</field1>
    <field2>This is the value in field2 from the XML file</field2>
    <field3>This is the value in field3 from the XML file</field3>
</mydata>

注释1 :这只是用于创建Word模板的示例XML .从模板生成Word文档时,以后可以应用具有相同格式的真实数据的XML文件.

Note 1: This is will be just a sample XML to create your Word template. XML file(s) with real data in this same format can later be applied when generating Word document(s) from the template.

注释2 :xmlns属性可以包含您想要的任何内容,并且不必是以http开头的URL.

Note 2: The xmlns attribute can contain literally anything you want and it doesn't have to be a URL starting with http.

将示例XML文件保存到任何位置,以便可以将其导入到您要创建的模板中.

Save your sample XML file to any location so that it can be imported to the template you are about to create.

  1. 确保在您的Word [File-> Options-> Customize Ribbon->副本上启用了Developer选项卡,在Customize the Ribbon下,确保选择了Developer-> OK].详细信息:如何:在功能区上显示开发人员"选项卡

  1. Make sure the Developer tab is enabled on your copy of Word [File -> Options -> Customize Ribbon -> Under Customize the Ribbon, make sure Developer is selected -> OK]. Details: How to: Show the Developer Tab on the Ribbon

创建一个新的Word文档(或使用现有的Word文档),它将作为生成文档的模板.

Create a new Word document (or use an existing Word document) which will be your template for document generation.

Developer选项卡上,单击XML Mapping Pane.这将打开文档右侧的XML Mapping Pane.

On the Developer tab, click on XML Mapping Pane. This will open the XML Mapping Pane on the right side of the document.

在XML映射窗格上,选择Custom XML Part下拉菜单->选择(Add new part).

On the XML Mapping Pane, select the Custom XML Part drop down -> Select (Add new part).

选择在步骤1-> Open中保存的XML文件.

Select the XML file that you saved on step 1 -> Open.

在XML映射窗格上,选择Custom XML Part下拉菜单->选择带有自定义XML文件的xmlns属性上的文本的项目.如果您使用上面的示例文件,则为http://CustomDemoXML.htm.

On the XML Mapping Pane, select the Custom XML Part drop down -> Select the item with the text that was on the xmlns attribute of the custom XML file. If you use the sample file above, it would be http://CustomDemoXML.htm.

向Word文档中添加一些静态文本,并在其旁边添加Plain Text Content Control(在Developer选项卡-> Controls部分中.对需要添加的所有字段重复此操作.

Add a some static text to a Word document and add a Plain Text Content Control next to it (on the Developer tab -> Controls section. Repeat for all fields you need to add.

对于上面的示例XML,我有以下Word文档:

For the sample XML above, I had the following Word document:

  1. 单击第一个Plain Text Content Control->在XML Mapping Pane上,右键单击要映射到该内容控件的字段->单击Map to Selected Content Control.对要映射的所有字段重复上述操作.
  1. Click on the first Plain Text Content Control -> On the XML Mapping Pane, right click the field you want mapped to that content control -> Click Map to Selected Content Control. Repeat for all the fields you want to map.

注意:或者,您可以在XML Mapping Pane上右键单击要映射的字段,而不是在步骤#8中从开发人员标签添加Plain Text Content Control项->单击Insert Content Control->单击Plain Text.

Note: Alternatively, instead of adding the Plain Text Content Control items from the developer tab on step #8, you could right click on the field you want to map on the XML Mapping Pane -> Click Insert Content Control -> Click Plain Text.

类似地,您还可以添加其他类型的控件,例如复选框,日期选择器甚至是重复节(它也支持嵌套的重复节!-自Word 2013起),并将XML中的数据映射到仅使用本机Word功能且不使用XML的情况任何第三方工具!

Similarly, you can also add other types of controls such as checkboxes, date pickers and even repeating sections (it supports nested repeating sections too! - since Word 2013) and map data from XML to those using just native Word functionality and without any third party tools!

  1. 保存模板文档.


第2部分:使用C#中的代码基于模板生成文档

这使用Microsoft推荐的 OpenXML SDK 生成使用包含真实数据的XML文件创建文档.


Part 2: Use code in C# to generate documents based on template

This uses Microsoft's recommended OpenXML SDK to generate documents using an XML file containing real data.

  1. 构建您的XML文件/打开现有的XML文件,使用该文件可以从上面创建的模板生成文档.该格式必须与用于创建模板的示例XML文件的格式相同.

  1. Build your XML file/open an existing XML file with which to generate a document from the template created above. This needs to be in the same format as the sample XML file used to create the template.

使用OpenXML SDK从文档中删除任何CustomXMLPart元素.假定在文档中没有使用其他自定义XML部件(在本示例中就是这种情况).对于复杂的场景,您可以根据需要删除特定的XML部分.

Use the OpenXML SDK to delete any CustomXMLPart elements from the document. This assumes no other custom XML parts are used in the document which is the case in this example. For complex scenarios, you can delete specific XML parts if needed.

使用OpenXML SDK在上面的步骤1中基于XML文件添加新的CustomXMLPart.

Use the OpenXML SDK to add a new CustomXMLPart based on the XML file in step#1 above.

这是示例代码,我必须使用包含真实数据的XML文件中的数据刷新"/重新加载"模板中的示例数据(假设已经创建并保存了用于生成文档的XML文件) :

Here is the sample code I have to "refresh"/"reload" the sample data in the template with a data from an XML file containing real data (assuming the XML file used to generate the document is already created and saved):

using System.IO;
using DocumentFormat.OpenXml.Packaging;

namespace SampleNamespace
{
    public static class SampleClass
    {
        public static void GenerateDocument()
        {
            string rootPath = @"C:\Temp";
            string xmlDataFile = rootPath + @"\MyNewData.xml";
            string templateDocument = rootPath + @"\MyTemplate.docx";
            string outputDocument = rootPath + @"\MyGeneratedDocument.docx";

            using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templateDocument, true))
            {
                //get the main part of the document which contains CustomXMLParts
                MainDocumentPart mainPart = wordDoc.MainDocumentPart;

                //delete all CustomXMLParts in the document. If needed only specific CustomXMLParts can be deleted using the CustomXmlParts IEnumerable
                mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);

                //add new CustomXMLPart with data from new XML file
                CustomXmlPart myXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
                using (FileStream stream = new FileStream(xmlDataFile, FileMode.Open))
                {
                    myXmlPart.FeedData(stream);
                }
            }

        }
    }
}

就是这样!