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

sla*_*oah 4 c# xml ms-word openxml openxml-sdk

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

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

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

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

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

有人可以展示如何实现这一点的例子.只是一个简单的例子就足够了.

对于任何编码,我更喜欢C#.我正在使用Word 2016,但希望它从Word 2007兼容到Word 2016以及介于两者之间的所有内容,因为用户将使用这些版本.谢谢!

sla*_*oah 13

弄清楚如何使用内容控件生成文档以及如何将XML中的数据填充到内容控件中.我把它分为两部分:

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

第1部分:为文档生成创建模板文档

  1. 创建一个示例XML,您可以根据该XML创建用于文档生成的Word模板.最好从较不复杂的版本开始,以获得它的悬念.

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

<?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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

  4. 在XML Mapping Pane上,选择Custom XML Part下拉菜单 - > Select (Add new part).

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

  6. 在XML Mapping Pane上,选择Custom XML Part下拉菜单 - >选择xmlns包含自定义XML文件属性上的文本的项目.如果您使用上面的示例文件,它将是http://CustomDemoXML.htm.

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

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

示例word文档模板

  1. 单击第一个Plain Text Content Control- >在XML Mapping Pane上,右键单击要映射到该内容控件的字段 - >单击Map to Selected Content Control.对要映射的所有字段重复此操作.

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

同样,您还可以添加其他类型的控件,例如复选框,日期选择器甚至重复部分(它也支持嵌套的重复部分! - 自Word 2013以来),并将数据从XML映射到仅使用本机Word功能且没有任何第三方的数据工具!

  1. 保存模板文档.

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

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

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

  2. 使用OpenXML SDK删除CustomXMLPart文档中的任何元素.假设在本示例中没有在文档中使用其他自定义XML部件.对于复杂方案,您可以根据需要删除特定的XML部分.

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

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

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

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而已!


sla*_*oah 5

好的,在此处找到了有关使用 XSLT 作为模板生成 Word 文档的详细指南:使用 XSLT 和 Open XML 创建 Word 2007 文档

看起来即使这篇文章是针对 Word 2007 的,它在 Word 2016 中也能完美运行。

此方法的唯一问题是,如果稍后需要更改模板,更新 xslt 文件需要花费大量精力,这样做对用户不友好,因为它无法在 Word 本身和文档的实际 XML 中更新需要被操纵。

从好的方面来说,文档生成非常灵活,可以通过 XSL 获得所有可用的功能(foreach、变量、if 条件等)。