虽然可利用 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 中的代码,您必须向您的项目添加引用。虽然示例项目包含这些引用,但您必须在您的代码中显式引用以下程序集:
您还应将下面的 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 文档"选项卡,并搜索要研究的类。尽管该文档当前不包含代码示例,但借助此处所示的示例和文档,您应能成功修改示例应用程序。 |