SharePoint 2010: 如何使用Word Automation Services开发应用

内容

  • 使用Word Automation Services更改文档格式
  • 一个使用Word Automation Services的场景
  • Word Automation Services工作原理
  • 构建Word Automation Services应用
  • 监控文档转换状态
  • 辨别转换失败的文档
  • 转换完成后删除源文件
  • 与Open XML SDK进行集成
  • 总结
  • 其它资源

源代码下载

使用Word Automation Services更改文档格式

当我们使用Open XML SDK 2.0 for Microsoft Office时,有些任务是比较困难的。比如:重新编排页码,将文档转换为诸如PDF等的其它格式,或者更新文档目录表、字段,以及文档中的其它动态内容。而SharePoint 2010提供的Word Automation Services新功能就是用来解决这些问题的。

Word Automation Services是一个共享服务,它无需人员参与,可以在服务器端执行文档格式转换以及其它重要功能。其最初设计理念是在服务器端以可靠和可预测的方式处理多个文档。

我们可以使用Word Automation Services将Open XML WordprocessingML格式转换成其它格式。比如:可以将多个文档转换成PDF格式然后发送到打印机的打印池,或者通过邮件将PDF文档发送给客户,也可以将其它格式的文档(如:HTML,Word 97-2003二进制格式)转换成Open XML work-processing文档。

除了进行文档格式转换,Word Automation Services还提供了其它一些重要功能。比如:更新文档中的字段,将altChunk内容转换成使用正常格式的段落。如果我们使用Open XML SDK执行这些工作是非常困难的,但是Word Automation Services做这些工作就非常容易。以前,我们使用Word Automation Services为客户端执行这些工作,但这是有问题的。Word客户端更适合进行交互式文档编写,而不是用来在服务器端进行多文档处理的。如果在Word中执行这些任务,Word往往会显示错误提示框,而且如果服务器自动操作Word客户端,又没有用户响应对话框,这样线程就无法停止。这是一个与Word自动化相关的问题,有一篇KB专门介绍,Considerations for Server-side Automation of Office

一个使用Word Automation Services的场景

下面这个场景展示了如何使用Word Automation Services在服务器端自动处理文档。

  • 某位专家遵循一定的规范创建了一些Word模板,她或许会使用内容控制为这些模板提供一些使用指导,这为在文档生成过程中确定数据应该出现在文档模板的哪些位置提供了良好的用户体验和可靠的编程方法。通常,这些文档模板保存在SharePoint文档库里。
  • 运行在服务器端的程序把文档模板和数据结合在一起,形成Open XML WordprocessingML (DOCX)文档。最好的方法是使用Open XML SDK 2.0 for Microsoft Office编写这个程序,因为这个SDK专门用来在服务器端生成文档。这些文档存放在SharePoint文档库里。
  • 文档自动生成后,可能需要被打印,然后转换为WordprocessingML、PDF、XPS或MHTML格式再通过邮件发送给一系列用户。
  • 作为转换工作的一部分,我们可以使用Word Automation Services更新文档中的字段,比如:文档目录表。

一起使用Open XML SDK 2.0 for Microsoft Office以及Word Automation Services可以创建丰富的、端到端解决方案,而无须自动化Word客户端应用。

Word Automation Services的一个突出优点是可以进行扩展升级,而Word客户端应用无法做到这点,我们可以配置Word Automation Services使用多个处理器,如果需要,还可以配置为负载均衡。

另外一个突出优点是,Word Automation Services在文档布局(包括分页排版)方面保持了与Word客户端近乎完全一致的体验。无论文档是在服务器端处理的,还是在客户端处理的,其布局都是完全一致的。

支持的源文档格式

  • Open XML File Format documents (.docx, .docm, .dotx, .dotm)
  • Word 97-2003 documents (.doc, .dot)
  • Rich Text Format files (.rtf)
  • Single File Web Pages (.mht, .mhtml)
  • Word 2003 XML Documents (.xml)
  • Word XML Document (.xml)

支持的目标文档格式

  • Portable Document Format (.pdf)
  • Open XML Paper Specification (.xps)

Word Automation Services的其它功能

除了加载文档并将文档保存为其它格式外, Word Automation Services还具有其它一些功能。

我们可以使用Word Automation Services更新文档目录、table of authorities以及索引字段,这在生成文档时非常重要。如果文档在生成后,其目录表未能正确更新,那么确定文档的分页将是非常困难的工作,而Word Automation Services可以非常容易地处理这个工作。

Open XML word-processing文档包含各式各样的字段类型,使用这些字段类型我们可以为文档动态添加内容。我们可以使用Word Automation Services重新计算所有的字段。比如:为文档添加一个插入当前日期的字段类型。这样当所有字段被更新时,其关联的内容也随之被更新,这样文档就可以在字段所在位置显示当前日期。

使用内容控制的一个最有效途径是将内容绑定到一个自定义XML元素。关于如何进行绑定,请参考Building Document Generation Systems from Templates with Word 2010 and Word 2007,以及其它一些资源。通过替换自定义XML元素可以将绑定内容控件的内容进行更新,而无须更改文档主体。文档主体包含了所有绑定内容控件的缓存值,如果只是替换自定义XML元素,文档主体中的缓存值是不会被更新的。如果用户只是用Word客户端应用查看就不会有这个问题,但是,如果要更深地处理WordprocessingML markup,我们就必须更新文档主体中的缓存值。而Word Automation Services正好可以做这项工作。

更换以altChunk元素表示的格式内容,是将HTML内容导入到WordprocessingML文档的好办法。Building Document Generation Systems from Templates with Word 2010 and Word 2007探讨了如何更换格式内容,使用方法,并且提供了其它开始资源。但是,这需要一直到你打开和保存包含altChunk元素的文档时才可以。这个文档包含HTML,而没有常规的的WordprocessingML markup,比如:段落,runs 以及文本。现在我们可以使用Word Automation Services导入HTML(或其它格式的可更换内容),然后将它们转换为WordprocessingML markup,这样WordprocessingML段落就有了styles。

也可以把以往的Word版本格式进行转换。比如,要构建的企业级应用有几千个用户,而他们当中就有一些人在Word 2007或Word 2003编辑Open XML文档,这时候,我们就可以将Open XML文档转换成与Word 2007或Word 2003兼容的格式。

Word Automation Services的不足

Word Automation Service缺少打印功能,但是,我们可以直接将WordprocessingML文档转换为PDF或XPS格式然后再打印。

有人可能会问,是否可以不采购和安装SharePoint Server 2010就可以使用Word Automation Services呢?答案是:Word Automation Services依赖于SharePoint 2010的其它功能,它只是SharePoint 2010的一个功能,我们购买并且安装SharePoint Server 2010才可以使用它。SharePoint 2010的标准版和企业版都包含Word Automation Services。

Word Automation Services工作原理

默认情况下,Word Automation Services随SharePoint Server 2010一起安装并且运行。如果在服务器场中使用SharePoint 2010,必须专门启用Word Automation Services。

要使用Word Automation Services,可以使用其编程接口启动转换工作(conversion job),对于每项转换工作需要指定要转换的文件、文件夹或者文档库。转换工作启动时,根据用户的配置信息,Word Automation Services在每台服务器上启动指定数量的转换线程。可以指定转换工作的执行频率,还可以指定每个转换线程执行的转换的数量。另外,还可以Word Automation Services可以使用的最大内存的百分比。

可以配置Word Automation Services,以保证其不过分使用SharePoint服务器的资源,你可以根据对SharePoint服务器的使用期望来决定该如何配置Word Automation Services。如果只是用Word Automation Services执行文档转换,你可以考虑让Word Automation Services占用大部分的processor time。当然,如果要执行的是低优先级的后台转换,你需要相应进行配置。

重要提示

  • 建议worker process占用的处理器的数量绝对不要超过服务器减一。比如:对于4核服务器i,转换线程最多不能超过3个。
  • 如果是在服务器场中,worker process占用的处理器数量不超过服务器场中有最少处理器那台服务器的处理器减一。
  • 建议每分钟每个worker process最多处理90个文档转换。

编写代码除了可以启动转换实例外,还可以监控转换过程,这样当较大的转换工作完成时就可以同志用户或者发出提示。

Word Automation Services还可以进行4个方面的转换配置。

  • 限制支持的文档格式的数量。
  • 设置转换线程重启时可以转换的文档的数量。这非常有价值,因为无效文档会导致Word Automation Services消耗过多的内存资源。
  • 设置Word Automation Services尝试转换文档的次数。默认情况下,这个值为2,也就是说,如果Word Automation Services转换某个文档失败,它只会再尝试一次(在当时那个conversion job中)。
  • 设置转换线程开始后多久才开始监控。这非常有价值,因为Word Automation Services可以监控转换以确保每个转换进程没有停滞。

配置Word Automation Services

无论是否安装服务器场,默认情况下,Word Automation Services都随SharePoint Server 2010安装并运行。但开发人员可能需要更改其配置以获取更好的开发体验。默认情况下,转换线程每15分钟执行一次,如果是为了测试代码,更改为每分钟允许一次更好。另外,在测试过程中让Word Automation Services使用更多的资源是更好的主意。

调整转换线程每分钟执行一次

  1. 打开SharePoint 2010 Central Administration
  2. SharePoint 2010 Central Administration首页,点击Manage Service Applications
  3. Service Applications管理页,服务是按字母排序的。点击Word Automation Services。如果Word Automation Services是手动安装的,可能名称会有所不同。
  4. Word Automation Services管理页,相应配置即可。
  5. 点击OK

构建Word Automation Services应用

Because Word Automation Services is a service of SharePoint Server 2010, you can only use it in an application that runs directly on a SharePoint Server. You must build the application as a farm solution. You cannot use Word Automation Services from a sandboxed solution.

A convenient way to use Word Automation Services is to write a web service that you can use from client applications.

However, the easiest way to show how to write code that uses Word Automation Services is to build a console application. You must build and run the console application on the SharePoint Server, not on a client computer. The code to start and monitor conversion jobs is identical to the code that you would write for a Web Part, a workflow, or an event handler. Showing how to use Word Automation Services from a console application enables us to discuss the API without adding the complexities of a Web Part, an event handler, or a workflow.

重要提示:

Note that the following sample applications call Sleep so that the examples query for status every five seconds. This would not be the best approach when you write code that you intend to deploy on production servers. Instead, you want to write a workflow with delay activity.

To build the application

  1. Start Microsoft Visual Studio 2010.
  2. On the File menu, point to New, and then click Project.
  3. In the New Project dialog box, in the Recent Template pane, expand Visual C#, and then click Windows.
  4. To the right side of the Recent Template pane, click Console Application.
  5. By default, Visual Studio creates a project that targets .NET Framework 4.0. However, you must target .NET Framework 3.5. From the list at the upper part of the File Open dialog box, select .NET Framework 3.5.
  6. In the Name box, type the name that you want to use for your project, such as FirstWordAutomationServicesApplication.
  7. In the Location box, type the location where you want to place the project.
  8. Figure 1. Creating a solution in the New Project dialog box

  9. Click OK to create the solution.
  10. By default, Visual Studio 2010 creates projects that target x86 CPUs, but to build SharePoint Server applications, you must target any CPU.
  11. If you are building a Microsoft Visual C# application, in Solution Explorer window, right-click the project, and then click Properties.
  12. In the project properties window, click Build.
  13. Point to the Platform Target list, and select Any CPU.
  14. Figure 2. Target Any CPU when building a C# console application

  15. If you are building a Microsoft Visual Basic .NET Framework application, in the project properties window, click Compile.


  16. Figure 3. Compile options for a Visual Basic application

  17. Click Advanced Compile Options.
  18. Figure 4. Advanced Compiler Settings dialog box

  19. Point to the Platform Target list, and then click Any CPU.
  20. To add a reference to the Microsoft.Office.Word.Server assembly, on the Project menu, click Add Reference to open the Add Reference dialog box.
  21. Select the .NET tab, and add the component named Microsoft Office 2010 component.
  22. Figure 5. Adding a reference to Microsoft Office 2010 component

  23. Next, add a reference to the Microsoft.SharePoint assembly.
  24. Figure 6. Adding a reference to Microsoft SharePoint

The following examples provide the complete C# and Visual Basic listings for the simplest Word Automation Services application.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.SharePoint;

using Microsoft.Office.Word.Server.Conversions;

 

class Program

{

static void Main(string[] args)

{

string siteUrl = "http://localhost";

// If you manually installed Word automation services, then replace the name

// in the following line with the name that you assigned to the service when

// you installed it.

string wordAutomationServiceName = "Word Automation Services";

using (SPSite spSite = new SPSite(siteUrl))

{

ConversionJob job = new ConversionJob(wordAutomationServiceName);

job.UserToken = spSite.UserToken;

job.Settings.UpdateFields = true;

job.Settings.OutputFormat = SaveFormat.PDF;

job.AddFile(siteUrl + "/Shared%20Documents/Test.docx",

siteUrl + "/Shared%20Documents/Test.pdf");

job.Start();

}

}

}

Note:

Replace the URL assigned to siteUrl with the URL to the SharePoint site.

To build and run the example

  1. Add a Word document named Test.docx to the Shared Documents folder in the SharePoint site.
  2. Build and run the example.
  3. After waiting one minute for the conversion process to run, navigate to the Shared Documents folder in the SharePoint site, and refresh the page. The document library now contains a new PDF document, Test.pdf.

监控文档转换状态

In many scenarios, you want to monitor the status of conversions, to inform the user when the conversion process is complete, or to process the converted documents in additional ways. You can use the ConversionJobStatus class to query Word Automation Services about the status of a conversion job. You pass the name of the WordServiceApplicationProxy class as a string (by default, "Word Automation Services"), and the conversion job identifier, which you can get from the ConversionJob object. You can also pass a GUID that specifies a tenant partition. However, if the SharePoint Server farm is not configured for multiple tenants, you can pass null (Nothing in Visual Basic) as the argument for this parameter.

After you instantiate a ConversionJobStatus object, you can access several properties that indicate the status of the conversion job. The following are the three most interesting properties.

ConversionJobStatus Properties

Property

Return Value  

Count

Number of documents currently in the conversion job. 

Succeeded

Number of documents successfully converted. 

Failed

The number of documents that failed conversion. 

Whereas the first example specified a single document to convert, the following example converts all documents in a specified document library. You have the option of creating all converted documents in a different document library than the source library, but for simplicity, the following example specifies the same document library for both the input and output document libraries. In addition, the following example specifies that the conversion job should overwrite the output document if it already exists.

Console.WriteLine("Starting conversion job");

ConversionJob job = new ConversionJob(wordAutomationServiceName);

job.UserToken = spSite.UserToken;

job.Settings.UpdateFields = true;

job.Settings.OutputFormat = SaveFormat.PDF;

job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;

SPList listToConvert = spSite.RootWeb.Lists["Shared Documents"];

job.AddLibrary(listToConvert, listToConvert);

job.Start();

Console.WriteLine("Conversion job started");

ConversionJobStatus status = new ConversionJobStatus(wordAutomationServiceName,

job.JobId, null);

Console.WriteLine("Number of documents in conversion job: {0}", status.Count);

while (true)

{

Thread.Sleep(5000);

status = new ConversionJobStatus(wordAutomationServiceName, job.JobId,

null);

if (status.Count == status.Succeeded + status.Failed)

{

Console.WriteLine("Completed, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed);

break;

}

Console.WriteLine("In progress, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed);

}

To run this example, add some WordprocessingML documents in the Shared Documents library. When you run this example, you see output similar to this code snippet,

识别转换失败的文档

You may want to determine which documents failed conversion, perhaps to inform the user, or take remedial action such as removing the invalid document from the input document library. You can call the GetItems method, which returns a collection of ConversionItemInfo objects. When you call the GetItems method, you pass a parameter that specifies whether you want to retrieve a collection of failed conversions or successful conversions. The following example shows how to do this.

Console.WriteLine("Starting conversion job");

ConversionJob job = new ConversionJob(wordAutomationServiceName);

job.UserToken = spSite.UserToken;

job.Settings.UpdateFields = true;

job.Settings.OutputFormat = SaveFormat.PDF;

job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;

SPList listToConvert = spSite.RootWeb.Lists["Shared Documents"];

job.AddLibrary(listToConvert, listToConvert);

job.Start();

Console.WriteLine("Conversion job started");

ConversionJobStatus status = new ConversionJobStatus(wordAutomationServiceName,

job.JobId, null);

Console.WriteLine("Number of documents in conversion job: {0}", status.Count);

while (true)

{

Thread.Sleep(5000);

status = new ConversionJobStatus(wordAutomationServiceName, job.JobId, null);

if (status.Count == status.Succeeded + status.Failed)

{

Console.WriteLine("Completed, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed);

ReadOnlyCollection<ConversionItemInfo> failedItems =

status.GetItems(ItemTypes.Failed);

foreach (var failedItem in failedItems)

Console.WriteLine("Failed item: Name:{0}", failedItem.InputFile);

break;

}

Console.WriteLine("In progress, Successful: {0}, Failed: {1}", status.Succeeded,

status.Failed);

}

To run this example, create an invalid document and upload it to the document library. An easy way to create an invalid document is to rename the WordprocessingML document, appending .zip to the file name. Then delete the main document part (known as document.xml), which is in the Word folder of the package. Rename the document, removing the .zip extension so that it contains the normal .docx extension.

代码输出如下。

Starting conversion job

Conversion job started

Number of documents in conversion job: 5

In progress, Successful: 0, Failed: 0

In progress, Successful: 0, Failed: 0

In progress, Successful: 4, Failed: 0

In progress, Successful: 4, Failed: 0

In progress, Successful: 4, Failed: 0

Completed, Successful: 4, Failed: 1

Failed item: Name:http://intranet.contoso.com/Shared%20Documents/IntentionallyInvalidDocument.docx

另外一种监控转换过程的方法是使用SharePoint List Event Handler捕捉转换后的文档添加到文档库时的动作。

转换完成后删除源文件

文档转换完毕后,如果要删除源,可以使用下面的示例代码。

Console.WriteLine("Starting conversion job");

ConversionJob job = new ConversionJob(wordAutomationServiceName);

job.UserToken = spSite.UserToken;

job.Settings.UpdateFields = true;

job.Settings.OutputFormat = SaveFormat.PDF;

job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;

SPFolder folderToConvert = spSite.RootWeb.GetFolder("Shared Documents");

job.AddFolder(folderToConvert, folderToConvert, false);

job.Start();

Console.WriteLine("Conversion job started");

ConversionJobStatus status = new ConversionJobStatus(wordAutomationServiceName,

job.JobId, null);

Console.WriteLine("Number of documents in conversion job: {0}", status.Count);

while (true)

{

Thread.Sleep(5000);

status = new ConversionJobStatus(wordAutomationServiceName, job.JobId, null);

if (status.Count == status.Succeeded + status.Failed)

{

Console.WriteLine("Completed, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed);

Console.WriteLine("Deleting only items that successfully converted");

ReadOnlyCollection<ConversionItemInfo> convertedItems =

status.GetItems(ItemTypes.Succeeded);

foreach (var convertedItem in convertedItems)

{

Console.WriteLine("Deleting item: Name:{0}", convertedItem.InputFile);

folderToConvert.Files.Delete(convertedItem.InputFile);

}

break;

}

Console.WriteLine("In progress, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed);

}    

Console.WriteLine("Starting conversion job")

Dim job As ConversionJob = New ConversionJob(wordAutomationServiceName)

job.UserToken = spSite.UserToken

job.Settings.UpdateFields = True

job.Settings.OutputFormat = SaveFormat.PDF

job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite

Dim folderToConvert As SPFolder = spSite.RootWeb.GetFolder("Shared Documents")

job.AddFolder(folderToConvert, folderToConvert, False)

job.Start()

Console.WriteLine("Conversion job started")

Dim status As ConversionJobStatus = _

New ConversionJobStatus(wordAutomationServiceName, job.JobId, Nothing)

Console.WriteLine("Number of documents in conversion job: {0}", status.Count)

While True

Thread.Sleep(5000)

status = New ConversionJobStatus(wordAutomationServiceName, job.JobId, _

Nothing)

If status.Count = status.Succeeded + status.Failed Then

Console.WriteLine("Completed, Successful: {0}, Failed: {1}", _

status.Succeeded, status.Failed)

Console.WriteLine("Deleting only items that successfully converted")

Dim convertedItems As ReadOnlyCollection(Of ConversionItemInfo) = _

status.GetItems(ItemTypes.Succeeded)

For Each convertedItem In convertedItems

Console.WriteLine("Deleting item: Name:{0}", convertedItem.InputFile)

folderToConvert.Files.Delete(convertedItem.InputFile)

Next

Exit While

End If

Console.WriteLine("In progress, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed)

End While

与Open XML SDK进行集成

The power of using Word Automation Services becomes clear when you use it in combination with the Welcome to the Open XML SDK 2.0 for Microsoft Office. You can programmatically modify a document in a document library by using the Welcome to the Open XML SDK 2.0 for Microsoft Office, and then use Word Automation Services to perform one of the difficult tasks by using the Open XML SDK. A common need is to programmatically generate a document, and then generate or update the table of contents of the document. Consider the following document, which contains a table of contents.

Figure 7. Document with a table of contents

Let's assume you want to modify this document, adding content that should be included in the table of contents. This next example takes the following steps.

  1. Opens the site and retrieves the Test.docx document by using a Collaborative Application Markup Language (CAML) query.
  2. Opens the document by using the Open XML SDK 2.0, and adds a new paragraph styled as Heading 1 at the beginning of the document.
  3. Starts a conversion job, converting Test.docx to TestWithNewToc.docx. It waits for the conversion to complete, and reports whether it was converted successfully.

Console.WriteLine("Querying for Test.docx");

SPList list = spSite.RootWeb.Lists["Shared Documents"];

SPQuery query = new SPQuery();

query.ViewFields = @"<FieldRef Name='FileLeafRef' />";

query.Query =

@"<Where>

<Eq>

<FieldRef Name='FileLeafRef' />

<Value Type='Text'>Test.docx</Value>

</Eq>

</Where>";

SPListItemCollection collection = list.GetItems(query);

if (collection.Count != 1)

{

Console.WriteLine("Test.docx not found");

Environment.Exit(0);

}

Console.WriteLine("Opening");

SPFile file = collection[0].File;

byte[] byteArray = file.OpenBinary();

using (MemoryStream memStr = new MemoryStream())

{

memStr.Write(byteArray, 0, byteArray.Length);

using (WordprocessingDocument wordDoc =

WordprocessingDocument.Open(memStr, true))

{

Document document = wordDoc.MainDocumentPart.Document;

Paragraph firstParagraph = document.Body.Elements<Paragraph>()

.FirstOrDefault();

if (firstParagraph != null)

{

Paragraph newParagraph = new Paragraph(

new ParagraphProperties(

new ParagraphStyleId() { Val = "Heading1" }),

new Run(

new Text("About the Author")));

Paragraph aboutAuthorParagraph = new Paragraph(

new Run(

new Text("Eric White")));

firstParagraph.Parent.InsertBefore(newParagraph, firstParagraph);

firstParagraph.Parent.InsertBefore(aboutAuthorParagraph,

firstParagraph);

}

}

Console.WriteLine("Saving");

string linkFileName = file.Item["LinkFilename"] as string;

file.ParentFolder.Files.Add(linkFileName, memStr, true);

}

Console.WriteLine("Starting conversion job");

ConversionJob job = new ConversionJob(wordAutomationServiceName);

job.UserToken = spSite.UserToken;

job.Settings.UpdateFields = true;

job.Settings.OutputFormat = SaveFormat.Document;

job.AddFile(siteUrl + "/Shared%20Documents/Test.docx",

siteUrl + "/Shared%20Documents/TestWithNewToc.docx");

job.Start();

Console.WriteLine("After starting conversion job");

while (true)

{

Thread.Sleep(5000);

Console.WriteLine("Polling...");

ConversionJobStatus status = new ConversionJobStatus(

wordAutomationServiceName, job.JobId, null);

if (status.Count == status.Succeeded + status.Failed)

{

Console.WriteLine("Completed, Successful: {0}, Failed: {1}",

status.Succeeded, status.Failed);

break;

}

}

运行代码后生成的新文档如下图。

8. 更新后的文档目录

总结

尽管Open XML SDK 2.0是非常强大的开发服务器端文档生成和处理系统的工具,但其在文档操作的其它方面功能有限,比如:进行文档格式转换,或者更新文档目录、字段等等。Word Automation Services弥补了其不足,并且提供了高可用性的解决方案。结合Open XML SDK 2.0使用Word Automation Services能够解决单独使用Open XML SDK 2.0时无法解决的很多难题。

其它资源

posted @ 2010-06-25 15:28  老猴  阅读(2127)  评论(0编辑  收藏  举报