在现代软件开发中,Office报告生成的需求日益增长。随着Open XML格式的普及,Office报告生成的理念发生了深刻变化,使其脱离了Office本身,并向任何能够读取压缩档案和操作XML的编程语言开放。本文将展示如何在分布式环境中生成Docx报告,同时确保MS Office 2007仅在开发机器上安装(而非生产服务器)。
该应用程序由以下几部分组成:
本文的范围限于前两个层次。通过使用Open XML SDK(现在为2.0版本),可以以编程方式读取和写入Office Open XML包内的内容,即无需使用Office COM对象即可读取和写入Office文件。这种方法非常快速、简单、资源占用少且稳定。
首先,需要构建一个Docx文档,该文档定义了报告的布局,使用Word 2007或更高版本。在该文档中,将包含静态部分(文本块、图像等)和动态部分,后者将依赖于数据。最初,需要构建并格式化Docx文件,使其看起来与动态数据在其上时的预期外观一致。然后,当对外观感到满意时,就是添加内容控件的时候了。在Word功能区中,需要转到“开发人员”选项卡(如果看不到它,请)。在这个选项卡中,可以找到一些内容控件,如富文本、纯文本、图像等。现在,需要用适当的内容控件替换放入文档中的示例静态数据。
使用Word 2007,可以将内容控件放入Docx文档中,但无法将这些控件绑定到自定义数据。为了做到这一点,要么需要“手动”修改Docx存档内的XML文件,要么采用更简单的方法,使用像这样的工具。目前,Docx文档不包含任何自定义XML部分。可以使用WCCT创建这些部分。在WCCT中打开Docx文档。在右侧面板上,点击“创建新的自定义XML部分”。自定义XML部分将被创建,将能够在“绑定视图”选项卡中看到它。在窗口的左侧部分,将能够看到插入文件的内容控件的引用。点击右侧面板的“编辑视图”选项卡,可以编辑XML。需要创建的XML结构必须是有效的,并且需要与页面上的内容控件相对应。例如:
<documentData>
<title alias="Title">
document title
</title>
<body alias="Body">
document body
</body>
</documentData>
创建完XML后,最好使用WCCT通过点击“检查语法”按钮来检查XML语法。现在准备返回到“绑定视图”。现在能够在树状结构中看到刚刚插入的XML节点,有趣的部分即将开始。现在将XML节点绑定到内容控件,这就像拖放一样简单。在右侧面板上选择一个节点,然后将其拖放到文档中一个内容控件的引用上。重复此操作,直到所有内容控件都绑定到数据。完成后,保存文件并点击预览按钮使用Word打开文档。注意自定义XML数据如何替换内容控件内的文本。
WCF服务将替换Docx模板中的自定义XML,用业务逻辑XML数据替换。使用Open XML SDK,这实际上非常简单。以下是replaceCustomXML方法:
private void replaceCustomXML(string docxTemplate, string customXML)
{
try
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(
docxTemplate,
true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);
CustomXmlPart customXmlPart = mainPart.AddCustomXmlPart(
CustomXmlPartType.CustomXml);
using (StreamWriter ts = new StreamWriter(customXmlPart.GetStream()))
ts.Write(customXML);
}
}
catch (Exception ex)
{
throw new FaultException(
"WCF error!\r\n" + ex.Message);
}
}
ASP.NET客户端将有一个template.xml文件,该文件复制了服务器上Docx模板中自定义XML部分的结构。理想情况下,将有一个网页自动生成用于输入数据的Web控件,这些数据的结构与XML模板文件的结构相匹配。输入数据后,Web客户端必须组成一个XML文档,该文档遵循现有的template.xml结构,但用用户输入的数据替换数据。然后,将XML字符串发送到WCF服务,该服务返回Docx文件的字节。然后,这些字节可以直接保存在服务器上的Docx文件中,或者通过HTTP直接发送给客户端。