使用 OpenXML SDK 2.0 的开源 Word 生成器

  • Roopesh Shenoy
  • 高翌翔

2012 年 2 月 13 日

话题:开源语言 & 开发

用于微软 Office 的OpenXML SDK 2.0提供了一些用于操作 Open XML 文档的强类型部件类(strongly typed part classes)。WorddocGenerator是一款开源工具,用于生成可驱动 word 文件的模板,它是一个对于用此 SDK 能做些什么的示例。InfoQ 与此工具的开发者Atul Verma取得了联系,并问了他几个关于此项目的问题。

 

InfoQ:worddocgenerator 与FlexDoc等其他文档生成器有何不同?

Atul:这个工具

  • 对于文档生成无需安装 Word
  • 采用 Open Xml 2.0 和 Visual Studio 2010
  • 将内容控件(Content Controls)用于文档生成
  • 提供了大量示例,包括许多生成 Word 文档的方法,例如
    • 使用 C# 设置内容(而非数据绑定)
    • 数据绑定内容控件
    • XPath 表达式
    • 使用 Xml 生成,即 XNode 或实体类,例如 Order(订单)

虽然我从未用过 FlexDoc,但是在其主页上我看到一则警告消息,即“警告:当前 fleXdoc 版本所依赖的一个 Microsoft Word 的功能由于专利问题已从 Office 2010 中被移除!此专利问题同样适用于一些在 2009 年 11 月之后发布的 Office 2007 的美国版本。”倘若果真如此,那么 FlexDoc 似乎并不适用于文档生成。

InfoQ:是如何使那些可刷新组件(refreshable components)工作的?他们是否会连接到服务器以获取数据?

Atul:该工具要求对于每个需要用数据填充的内容控件,我们需要在 Word 模板中为其指定一个标记(Tag)。在文档生成的时候,我们需要将该标记相应地映射为 PlaceHolderType 枚举。PlaceHolders 的类型有

——Recursive(循环):此类型对应到在模板与数据之间具有一对多(1:N)关系的控件,即例如重复某个项目列表(a list of Items)。

——Non-Recursive(非循环):此类型对应到在模板与数据之间具有一对一(1:1)关系的控件,即例如显示某个用户名。

——Ignore(忽略):对于这些控件无须执行任何操作。

——Container(容器):此类型仅用于可刷新文档(refreshable documents)。在首次从模板生成文档时,我们将此容器区域(container region)保存在 CustomXmlPart 部件中。从下次开始,我们会检索被保存的容器区域,并刷新该文档。这使得该文档可以自刷新(self-refreshable)。

我将用这个例子来解释刷新操作。我拥有一个模板,例如“Test.docx”。并取得了生成文档所需的数据对象,例如从我的数据层(通过数据库)得到的 Order(订单)对象。从模板首次生成文档时,那些(Container 类型的)内容控件被保存至 CustomXmlPart 部件。比如说,生成的文档是“TestOut.docx”。比如说,那个订单发生了一处更改。这意味着我需要刷新该文档以便与数据库保持同步。我将取得该文档,即“TestOut.docx”,和最新数据,即从数据层(通过数据库)取得的 Order(订单)对象,然后刷新该文档。由于该文档是可刷新的,因此我无需再刷新模板“Test.docx”。在此示例中,我已经包括了 PlaceHolders 控件的所有类型。

该工具需要一个文档、数据对象以及一个生成器,并返回生成的文档。如何取得数据不是必需的。对于文档生成无需安装 Word。

我已经添加了一个示例,用于展示使用 Word 2010 中的文档级自定义项(document-level customizations)从 Word 中(例如在文档上单击右键,并点击“刷新数据”)刷新此文档的方法之一。在此种特定情况下,工具可以驻留在服务器上(无需安装 Word),以便从(Word 文档拥有文档级自定义项的)客户端调用。更多信息请访问此链接

InfoQ:当为同一数据生成多份文档时性能如何?

Atul:虽然我没做过任何性能基准测试,但是文档生成是相当地快。因为我只是想从概念验证(POC,即 Proof Of Concept)或示例的角度,使用 Open Xml 2.0 SDK 来创建一款文档生成工具。我将在业余时间进行重构,在未来也会考虑性能问题。

InfoQ:是否可能有一款用于 Excel 的类似工具?

Atul:由于该工具特定于 Word 2007/Word 2010,因此它将不会用于 Excel。但是,使用 OpenXml 2.0 SDK 可以轻易创建用于 Excel 的类似工具或框架,例如ClosedXml就是这样一个项目。

InfoQ:这对于使用 OpenXML SDK 能做些什么是个很好的示例——在理想情况下,还会加入哪些其他有用的功能?

Atul:创建该工具的目的在于

  • 编写最少的代码来生成文档
  • 演示一些示例,以便使用下面列出的方法生成文档
    • 既能生成不可刷新(non-refreshable)文档,又能生成可刷新(refreshable)文档
    • 既可从对象(例如 Order 订单类)又可从 XmlNode(使用 XPath 表达式)生成文档
    • 使用 C# 设置内容控件的值
    • 使用数据绑定内容控件
    • 将一些文档追加至主文档

我想收集有关这些示例的反馈意见,而且此反馈功能应加入该工具中。

关于该工具的详细信息请查看这些博文第二部分),并把你的意见反馈给 Atul。了解更多有关 OpenXML SDK 2.0 信息,可参考XML in Office开发者资源,及MSDN

查看英文原文:Open Source Word Generator Using OpenXML SDK 2.0

开源语言 & 开发