使用 Open XML SDK 2.0 替换 Word 2010 文档中的 Styles 部分

Office 可视操作方法

**摘要:**使用 Open XML SDK 2.0 中的强类型类可将 Word 文档中的样式替换为一个包含 Microsoft Word 文档中的 styles 或 stylesWithEffects 部分的 XDocument 实例,而无需将该文档加载到 Word 中。

上次修改时间: 2015年3月9日

适用范围: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | VBA | Word 2007 | Word 2010

**发布时间:**2011 年 2 月

**供稿人:**Ken Getz,MCW Technologies, LLC(该链接可能指向英文页面)

概述

虽然可利用 Open XML 文件格式检索并修改 Word 文档中的内容块,但执行此操作需要做一些工作。Open XML SDK 2.0 添加了将简化对 Open XML 文件格式的访问的强类型类。SDK 将简化检索和替换任务,例如,一个包含文档 styles 或 stylesWithEffects 部分的 XDocument 实例。在给定 XML 内容的情况下,您可以对信息进行存档、修改并重新应用信息或将信息应用于新文档。此直观操作方法附带的代码示例将演示如何使用 SDK 替换 styles 或 stylesWithEffects 部分(假定您知道如何从现有文档中检索该部分)。有关如何从 Word 文档中检索 styles 或 stylesWithEffects 部分的详细信息,请参阅使用 Open XML SDK 2.0 从 Word 2010 文档中提取样式

编码

在给定一个包含 Word 2007 或 Word 2010 文档的相同部分的 XDocument 实例的情况下,此直观操作方法附带的示例将包含替换文档中的 styles 和 styleWithEffects 部分所需的代码。虽然该示例代码还包括检索作为 XDocument 实例的部分的过程,但此直观操作方法假定您知道如何做到这一点。以下各节将详细介绍这些代码。请注意,在 Word 2007 中创建的文档将只包含一个 styles 部分;Word 2010 额外添加了一个 stylesWithEffects 部分。为了使文档能够在 Word 2010 和 Word 2007 之间来回转换,Word 2010 保留了原始 styles 部分和新 styles 部分。Open XML 规范需要 Microsoft Word 忽略它无法识别的任何部分;Word 2007 无法识别由 Word 2010 添加到文档的 stylesWithEffects 部分。该代码示例演示了如何提取和替换这两个部分,不过该代码对这两个部分产生的效果相同。该示例代码会将这两个样式部分替换为指定的 XDocument 中的样式信息。

设置引用

若要使用 Open XML SDK 2.0 中的代码,您必须向您的项目添加几个引用。虽然示例项目已包含这些引用,但您必须在您的代码中显式引用以下程序集:

  • WindowsBase - 可以根据您创建的项目的类型为您设置此引用。

  • DocumentFormat.OpenXml - 由 Open XML SDK 2.0 安装。

还应将下面的 using/Imports 语句包含在代码文件的开头。

Imports System.IO
Imports System.Xml
Imports DocumentFormat.OpenXml.Packaging
using System.IO;
using System.Xml;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;

检查过程

WDReplaceStyles 过程接受三个参数:第一个参数包含一个指定要修改的文件的路径的字符串。第二个参数包含一个 XDocument,其中包含对其他 Word 文档中的样式内容的引用。第三个参数指示是要替换上一个 styles 部分还是更新的 stylesWithEffects 部分(您必须对 Word 2010 文档调用此过程两次,并将这些部分替换为源文档中的相应部分)。

Public Sub WDReplaceStyles(
  ByVal fileName As String, ByVal newStyles As XDocument,
  Optional ByVal setStylesWithEffectsPart As Boolean = True)
)
public static void WDReplaceStyles(
  string fileName, XDocument newStyles,
  bool setStylesWithEffectsPart = true)

此过程将检查您指定的文档,并查找带有效果的 styles 部分(或上一个 styles 部分)。如果请求的 styles 部分存在,则此过程会将提供的 XDocument 保存到所选的 styles 部分中。若要调用此过程,请传递所需的参数值,如示例代码中所示。若要使用该示例代码,请提供名为 C:\temp\StylesFrom.docx 和 C:\temp\StylesTo.docx 的文档。StylesFrom 文档应包含一些特定样式信息(它可能包含已修改的版本的内置样式:Header 1、Header 2 等),该示例可将这些信息复制到 StylesTo 文档中。该示例依赖示例代码中包含的 WDExtractStyles 过程。此过程还允许您选择是需要额外的 stylesWithEffects 部分还是较旧的 styles 部分。

Private Const fromDoc As String = "C:\Temp\StylesFrom.docx"
Private Const toDoc As String = "C:\Temp\StylesTo.docx"

Dim node = WDExtractStyles("C:\temp\StylesFrom.docx", True)
If node IsNot Nothing Then
  WDReplaceStyles("c:\temp\StylesTo.docx", node, True)
End If
const string fromDoc = @"C:\Temp\StylesFrom.docx";
const string toDoc = @"C:\Temp\StylesTo.docx";

var node = WDExtractStyles(@"C:\Temp\StylesFrom.docx", true);
if (node != null)
  WDReplaceStyles(@"C:\Temp\StylesTo.docx", node, true);

该示例代码将调用此相同的过程两次;对每个 styles 部分调用一次。如果传入不包含 stylesWithEffects 部分的 Word 2007 文档,则该代码会退出而不会尝试提取或替换该部分。

访问文档

该代码首先会使用 WordprocessingDocument.Open 方法打开文档,并指示应打开此文档以供读/写访问(最后的 true 参数)。在打开文档的情况下,该代码将使用 MainDocumentPart 属性导航到主文档,然后准备一个名为 stylesPart 的变量来保存对 styles 部分的引用。

Using document = WordprocessingDocument.Open(fileName, True)
  Dim docPart = document.MainDocumentPart
  Dim stylesPart As StylesPart = Nothing
  ' Code removed here…
End Using
using (var document = WordprocessingDocument.Open(fileName, true))
{
  var docPart = document.MainDocumentPart;

  StylesPart stylesPart = null;
  // Code removed here…
}

查找正确的 Styles 部分

接下来,该代码将使用 setStylesWithEffectsPart 布尔参数来检索对请求的 styles 部分的引用。然后,该代码将基于此值检索 docPart 变量的特定属性,并将其存储在 stylesPart 变量中。

If setStylesWithEffectsPart Then
  stylesPart = docPart.StylesWithEffectsPart
Else
  stylesPart = docPart.StyleDefinitionsPart
End If
if (setStylesWithEffectsPart)
  stylesPart = docPart.StylesWithEffectsPart;
else
  stylesPart = docPart.StyleDefinitionsPart;

保存部分内容

假定 styles 部分存在,则该代码必须将传递给此过程的 XDocument 的整个内容保存到 styles 部分。每个部分均提供一个用于返回 Stream 的 GetStream 方法。该代码会将 Stream 实例传递给 StreamWriter 类的构造函数,并创建围绕部分流的流编写器。最后,该代码将调用 XDocument 参数的 Save 方法,并将其内容保存到 styles 部分(在使用 XDocuments 和 Open XML 部分时,此步骤序列很常见,您会发现它经常被使用)。

If stylesPart IsNot Nothing Then
  newStyles.Save(New StreamWriter(
    stylesPart.GetStream(FileMode.Create, FileAccess.Write)))
End If
If stylesPart IsNot Nothing Then
  Using reader = XmlNodeReader.Create(
    stylesPart.GetStream(FileMode.Open, FileAccess.Read))
    ' Create the XDocument:
    styles = XDocument.Load(reader)
  End Using
End If
if (stylesPart != null)
{
  newStyles.Save(new StreamWriter(stylesPart.GetStream(
    FileMode.Create, FileAccess.Write)));
}

示例过程

下面的代码示例包含完整的示例过程。

Public Sub WDReplaceStyles(
  ByVal fileName As String, ByVal newStyles As XDocument,
  Optional ByVal setStylesWithEffectsPart As Boolean = True)

  Using document = WordprocessingDocument.Open(fileName, True)
    Dim docPart = document.MainDocumentPart

    Dim stylesPart As StylesPart = Nothing

    If setStylesWithEffectsPart Then
      stylesPart = docPart.StylesWithEffectsPart
    Else
      stylesPart = docPart.StyleDefinitionsPart
    End If
    If stylesPart IsNot Nothing Then
      newStyles.Save(New StreamWriter(
        stylesPart.GetStream(FileMode.Create, FileAccess.Write)))
    End If
  End Using
End Sub
public static void WDReplaceStyles(string fileName, 
  XDocument newStyles, 
  bool setStylesWithEffectsPart = true)
{
  using (var document = WordprocessingDocument.Open(fileName, true))
  {
    var docPart = document.MainDocumentPart;
 
    StylesPart stylesPart = null;
    if (setStylesWithEffectsPart)
      stylesPart = docPart.StylesWithEffectsPart;
    else
      stylesPart = docPart.StyleDefinitionsPart;
 
    if (stylesPart != null)
    {
      newStyles.Save(new StreamWriter(stylesPart.GetStream(
        FileMode.Create, FileAccess.Write)));
    }
  }
}
读取

此直观操作方法附带的示例演示的代码将检索 Word 文档中的两个 styles 部分,并会将信息保存到第二个文档的 styles 部分中。若要使用该示例,请安装 Open XML SDK 2.0(可通过"浏览"一节中列出的链接获得)。该示例还将使用作为 Open XML SDK 2.0 代码段集的一部分包含的修改后的代码。"浏览"一节还包括指向完整代码段集的链接,但您无需下载并安装代码段即可使用该示例。

如果您运行此直观操作方法中的示例代码,请先打开包含特定样式的源文档,在运行代码后,您应会发现这些样式将显示在输出文档中。此方法允许您创建可应用于文档的样式库。通常,您可以使用此方法修改文档模板,因为如果您使用的是 Word 样式,则您很可能会将您的文档基于定义其样式的特定模板。无论您是将样式直接应用于模板还是文档,都可使用此方法来修改样式,而无需在 Microsoft Word 中打开文档。

示例应用程序仅演示了在修改文档结构时可与之交互的由 Open XML SDK 2.0 提供的几个可用属性和方法。有关详细信息,请参阅 Open XML SDK 2.0 Productivity Tool 附带的文档:单击应用程序窗口左下角的"Open XML SDK 文档"选项卡,并搜索要研究的类。尽管文档并不总是包含代码示例,但借助此处所示的示例和文档,您应能够成功修改示例应用程序。

观看

观看视频

观看视频(该链接可能指向英文页面) | Length: 00:10:43

单击以获取代码

获取代码(该链接可能指向英文页面)

浏览

关于作者
Ken Getz 是 MCW Technologies 的高级顾问。他是 ASP.NET Developers Jumpstart(《ASP.NET 开发人员入门》,Addison-Wesley,2002)、Access Developer's Handbook(《Access 开发人员手册》,Sybex,2001)和 VBA Developer's Handbook, 2nd Edition(《VBA 开发人员手册第 2 版》,Sybex,2001)的合著者。