使用 Open XML SDK 2.0 将 Word 2010 文档从 DOCM 文件格式转换为 DOCX 文件格式

Office 可视操作方法

**摘要:**使用 Open XML SDK 2.0 中的强类型类可将包含 VBA 代码的 Word 文档(扩展名为 DOCM)转换为标准文档(扩展名为 DOCX),而无需将该文档加载到 Microsoft Word 中。

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

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

**发布时间:**2010 年 9 月

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

概述

虽然可利用 Open XML 文件格式以编程方式修改 Microsoft Word 文档的结构,但执行此操作需要做一些工作。Open XML SDK 2.0 添加了可简化对 Open XML 文件格式的访问的强类型类:SDK 将简化修改文档的各个部分这一任务。此直观操作方法附带的代码示例将介绍如何使用 SDK 做到这一点。

编码

此直观操作方法附带的示例包括将包含 VBA 代码的 Word 2007 或 Word 2010 文档(扩展名为 DOCM)转换为标准文档(扩展名为 DOCX)所需的代码。以下各节将详细介绍这些代码。

设置引用

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

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

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

您还应将下面的 using/Imports 语句添加到代码文件的顶部。

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

检查过程

WDConvertDOCMtoDOCX 过程接受一个指示要修改的文档的名称的参数(字符串)。

Public Sub WDConvertDOCMtoDOCX(ByVal fileName As String)
public static void WDConvertDOCMtoDOCX(string fileName)

此过程将修改您指定的文档,并验证该文档是否包含 VBA 部分,如果包含此部分,则将其删除。该代码在删除此部分后,将在内部更改文档类型并使用 DOCX 扩展名重命名文档。若要调用此过程,请传递参数值,如代码示例中所示。在运行此示例代码之前,请确保提供了一个名为 C:\temp\WithMacros.docm 的文档,该文档至少包含一个 VBA 过程。

WDConvertDOCMtoDOCX("C:\Temp\WithMacros.docm")
WDConvertDOCMtoDOCX("C:\\Temp\\WithMacros.docm");

访问文档

该代码首先会使用 WordprocessingDocument.Open 方法打开文档,并指示应打开该文档以供读写访问(最后的 true 参数)。然后,该代码将使用文字处理文档的 MainDocumentPart 属性的 Document 属性来检索对文档部分的引用。

Using document = WordprocessingDocument.Open(fileName, True)
  Dim docPart = document.MainDocumentPart.Document
  ' Code removed here…
End Using
using (var document = WordprocessingDocument.Open(fileName, true))
{
  var docPart = document.MainDocumentPart.Document;
  // Code removed here…
}

查找并删除 VBA 部分

如果传入的文档包含 VBA 代码,则该文档会将代码存储在离散 VBA 部分中。接下来,示例代码将验证该 VBA 部分是否存在,如果该部分存在,则将其删除并保存文档。为了查找该 VBA 部分,示例代码将检索文档的 VbaProjectPart 属性。该代码将调用 DeletePart 方法来删除 VBA 部分,然后调用文档的 Save 方法来保存更改。

' Look for the VBA part. If it is there, delete it.
Dim vbaPart = docPart.VbaProjectPart
If vbaPart IsNot Nothing Then
  docPart.DeletePart(vbaPart)
  docPart.Document.Save()
  ' Code removed here…
End If
var vbaPart = docPart.VbaProjectPart;
if (vbaPart != null)
{
  docPart.DeletePart(vbaPart);
  docPart.Document.Save();
  // Code removed here.
}

转换文档类型

仅从文档中删除 VBA 部分是远远不够的,您还必须在内部转换文档类型。Open XML SDK 2.0 提供了执行此任务的简单方法:您可以调用文档 ChangeDocumentType 方法并指示新的文档类型(在此示例中,将提供 WordProcessingDocumentType.Document 枚举值)。

您还必须重命名文件。但您无法在文件处于打开状态时执行此操作。using 块在该块末尾关闭文件。因此,您需要通过某种方式来指示该块后的代码您已修改文件:fileChanged 布尔变量将为您跟踪此信息。

' Change the document type so that it no 
' longer thinks it is macro-enabled.
document.ChangeDocumentType(WordprocessingDocumentType.Document)

' Track that the document has been changed.
fileChanged = True
// Change the document type so that it no 
// longer thinks it is macro-enabled.
document.ChangeDocumentType(
  WordprocessingDocumentType.Document);

// Track that the document has been changed.
fileChanged = true;

重命名文件

之后,该代码将重命名新修改的文档。为此,该代码将通过更改扩展名来计算新文件名;验证输出文件是否存在,如果该文件存在,则将其删除;最后,该代码会将文件从旧文件名移动到新文件名。

If fileChanged Then
  Dim newFileName = Path.ChangeExtension(fileName, ".docx")
  If File.Exists(newFileName) Then
    File.Delete(newFileName)
  End If
  File.Move(fileName, newFileName)
End If
if (fileChanged)
{
  var newFileName = Path.ChangeExtension(fileName, ".docx");
  if (File.Exists(newFileName))
  {
    File.Delete(newFileName);
  }
  File.Move(fileName, newFileName);
}

示例过程

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

Public Sub WDConvertDOCMtoDOCX(ByVal fileName As String)
  Dim fileChanged As Boolean = False

  Using document As WordprocessingDocument =
    WordprocessingDocument.Open(fileName, True)

    Dim docPart = document.MainDocumentPart

    ' Look for the VBA part. If it is there, delete it.
    Dim vbaPart = docPart.VbaProjectPart
    If vbaPart IsNot Nothing Then
      docPart.DeletePart(vbaPart)

      docPart.Document.Save()

      ' Change the document type so that it no 
      ' longer thinks it is macro-enabled.
      document.ChangeDocumentType(WordprocessingDocumentType.Document)

      ' Track that the document has been changed.
      fileChanged = True
    End If
  End Using

  ' If anything goes wrong in this file handling,
  ' the code will raise an exception back to the caller.
  If fileChanged Then
    Dim newFileName = Path.ChangeExtension(fileName, ".docx")
    If File.Exists(newFileName) Then
      File.Delete(newFileName)
    End If
    File.Move(fileName, newFileName)
  End If
End Sub
public static void WDConvertDOCMtoDOCX(string fileName)
{
  bool fileChanged = false;

  using (WordprocessingDocument document = WordprocessingDocument.Open(fileName, true))
  {
    var docPart = document.MainDocumentPart;
      // Look for the VBA part. If it is there, delete it.
    var vbaPart = docPart.VbaProjectPart;
    if (vbaPart != null)
    {
      docPart.DeletePart(vbaPart);
      docPart.Document.Save();

      // Change the document type so that it no 
      // longer thinks it is macro-enabled.
      document.ChangeDocumentType(
        WordprocessingDocumentType.Document);

      // Track that the document has been changed.
      fileChanged = true;
    }
  }

  // If anything goes wrong in this file handling,
  // the code will raise an exception back to the caller.
  if (fileChanged)
  {
    var newFileName = Path.ChangeExtension(fileName, ".docx");
    if (File.Exists(newFileName))
    {
      File.Delete(newFileName);
    }
    File.Move(fileName, newFileName);
  }
}
读取

此直观操作方法附带的示例演示了将使用 VBA 代码的文档(扩展名为 DOCM)转换为标准文档(扩展名为 DOCX)的代码。若要使用该示例,请安装 Open XML SDK 2.0(可通过"浏览"一节中列出的链接获得)。该示例还将使用作为 Open XML SDK 2.0 代码示例集的一部分包含的修改后的代码。"浏览"一节还包括指向完整代码示例集的链接。请注意,您无需下载并安装代码示例即可使用该示例。

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

观看

观看视频

观看视频(该链接可能指向英文页面) | 时长:00:06: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)的合著者。