使用 Open XML SDK 2.0 向 Word 2010 文档中添加表

Office 可视操作方法

**摘要:**使用 Open XML SDK 2.0 中的强类型类将简单表添加到 Word 2007 或 Word 2010 文档,而无需将该文档加载到 Microsoft Word 中。

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

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

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

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

概述

通过 Open XML 文件格式可与 Microsoft Word 文档交互并在其中创建表,但这样做需要执行一些操作。Open XML SDK 2.0 添加了用于简化对 Open XML 文件格式的访问的强类型类:SDK 简化了将信息插入文档的任务。此直观操作方法附带的代码示例将介绍如何使用 SDK 来实现此目标。

编码

此直观操作方法提供的示例包含将简单表插入 Word 2007 或 Word 2010 文档所需的代码。图 1 演示了示例应用程序创建的表。以下各节将详细讨论该代码。

图 1. 示例应用程序在现有 Word 文档中创建此简单表。

添加到 Word 文档中的表

设置引用

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

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

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

此外,应将以下 using/Imports 语句添加到代码文件的顶部。

Imports DocumentFormat.OpenXml
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Wordprocessing
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

检查过程

WDAddTable 过程接受两个参数,它们分别指示:

  • 要修改的文档的名称(字符串)。

  • 要作为表插入文档中的字符串二维数组。

Public Sub WDAddTable(ByVal fileName As String, 
                      ByVal data(,) As String)
public static void WDAddTable(string fileName, string[,] data)

该过程将修改您指定的文档,并在文档末尾添加一个包含您提供的二维数组中的信息的表。若要调用该过程,请传递这两个参数值,如示例代码中所示。在运行示例代码前,应验证是否提供了名为 C:\temp\AddTable.docx 的文档。

Const fileName As String = "C:\temp\AddTable.docx"
WDAddTable(fileName, New String(,) {
            {"Texas", "TX"},
            {"California", "CA"},
            {"New York", "NY"},
            {"Massachusetts", "MA"}})
const string fileName = @"C:\temp\AddTable.docx";
WDAddTable(fileName, new string[,] 
  { { "Texas", "TX" }, 
     { "California", "CA" }, 
     { "New York", "NY" }, 
     { "Massachusetts", "MA" } });

访问文档

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

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

创建 Table 对象并设置其属性

请先创建 Table 对象并设置其属性,然后才能将表插入文档中。若要设置表属性,请为 TableProperties 对象创建提供值。TableProperties 类提供了很多面向表的属性,如 Shading、TableBorders、TableCaption、TableCellSpacing 和 TableJustification。关键的一点是指定正确的属性值。示例过程包括以下代码。

Dim table As New Table()

Dim props As TableProperties = _
  New TableProperties(New TableBorders( _
  New TopBorder With {
    .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
    .Size = 12},
  New BottomBorder With {
    .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
    .Size = 12},
  New LeftBorder With {
    .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
    .Size = 12},
  New RightBorder With {
    .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
    .Size = 12}, _
  New InsideHorizontalBorder With {
    .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
    .Size = 12}, _
  New InsideVerticalBorder With {
    .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
    .Size = 12}))
table.AppendChild(Of TableProperties)(props)
Table table = new Table();

TableProperties props = new TableProperties(
  new TableBorders(
    new TopBorder { 
      Val = new EnumValue<BorderValues>(BorderValues.Single), 
      Size = 12 },
    new BottomBorder { 
      Val = new EnumValue<BorderValues>(BorderValues.Single), 
      Size = 12 },
    new LeftBorder { 
      Val = new EnumValue<BorderValues>(BorderValues.Single), 
      Size = 12 },
    new RightBorder { 
      Val = new EnumValue<BorderValues>(BorderValues.Single), 
      Size = 12 },
    new InsideHorizontalBorder { 
      Val = new Value<BorderValues>(BorderValues.Single), 
      Size = 12 },
    new InsideVerticalBorder { 
      Val = new EnumValue<BorderValues>(BorderValues.Single), 
      Size = 12 }));
table.AppendChild<TableProperties>(props);

TableProperties 类的构造函数可让您指定任意数量的子级(与 XElement 类的构造函数类似),在此例中,代码将创建 TopBorder、BottomBorder、LeftBorder、RightBorder、InsideHorizontalBorder 和 InsiderVerticalBorder 子元素,它们各自描述表的一个边框元素。在每一种情况中,代码都会将 Val 和 Size 属性设置为调用构造函数的一部分。设置大小很简单,但设置 Val 属性需要做更多工作:此特定对象的此属性表示边框样式,您必须将该属性设置为枚举值。若要执行该操作,请创建一个 EnumValue 泛型类型的实例,并将特定边框类型 (BorderValues.Single) 作为参数传递给构造函数。当代码设置完所有需要设置的表边框值之后,它会调用表的 AppendChild 方法,该方法指示泛型类型为 TableProperties。也就是说,该代码通过将变量 props 用作值来附加 TableProperties 类的实例。

使用数据填充表

在创建表及其属性之后,现在使用数据填充表。示例过程首先会循环访问您指定的字符串数组中的所有数据行,并为每行数据创建一个新的 TableRow 实例。下面的代码省去了用数据填充行的细节,但演示了如何创建行以及将行附加到表中。

For i = 0 To UBound(data, 1)
  Dim tr As New TableRow
  ' Code removed here…
  table.Append(tr)
Next
for (var i = 0; i <= data.GetUpperBound(0); i++)
{
  var tr = new TableRow();
  // Code removed here…
  table.Append(tr);
}

对于每一行,该代码会循环访问您指定的字符串数组中的所有列。对于每一列,该代码会创建一个新的 TableCell,用数据填充它,然后将它附加到行。下面的代码省略了用数据填充每个单元格的细节,但演示了如何创建列以及如何将列附加到表。

For j = 0 To UBound(data, 2)
  Dim tc As New TableCell
  ' Code removed here…
  tr.Append(tc)
Next
for (var j = 0; j <= data.GetUpperBound(1); j++)
{
  var tc = new TableCell();
  // Code removed here…
  tr.Append(tc);
}

接下来,该代码会创建包含字符串数组中的值的新 Text 对象,将该对象传递给新的 Run 对象的构造函数,再将该对象传递给新的 Paragraph 对象的构造函数,最后将该对象传递给单元格的 Append 方法。换句话说,该代码会将文本附加到新的 TableCell 对象。

tc.Append(new Paragraph(new Run(new Text(data[i, j]))));

该代码然后会将新的 TableCellProperties 对象附加到单元格。此 TableCellProperties 对象(如您见过的 TableProperties 对象)的构造函数中可接受您提供的任意数量的对象。在这种情况下,该代码只会传递一个新的 TableCellWidth 对象,其 Type 属性设置为 TableWidthUnitValues.Auto(以便表能自动调整每列的宽度大小)。

' Assume you want columns that are automatically sized.
tc.Append(New TableCellProperties(
  New TableCellWidth With {.Type = TableWidthUnitValues.Auto}))
// Assume you want columns that are automatically sized.
tc.Append(new TableCellProperties(
  new TableCellWidth { Type = TableWidthUnitValues.Auto }));

完成

该代码最后会将表附加到文档正文,然后保存该文档。

doc.Body.Append(table)
doc.Save()
doc.Body.Append(table);
doc.Save();

示例过程

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

Public Sub WDAddTable(ByVal fileName As String,
                      ByVal data(,) As String)
  Using document = WordprocessingDocument.Open(fileName, True)

    Dim doc = document.MainDocumentPart.Document

    Dim table As New Table()

    Dim props As TableProperties = _
      New TableProperties(New TableBorders( _
      New TopBorder With {
        .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
        .Size = 12},
      New BottomBorder With {
        .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
        .Size = 12},
      New LeftBorder With {
        .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
        .Size = 12},
      New RightBorder With {
        .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
        .Size = 12}, _
      New InsideHorizontalBorder With {
        .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
        .Size = 12}, _
      New InsideVerticalBorder With {
        .Val = New EnumValue(Of BorderValues)(BorderValues.Single),
        .Size = 12}))
    table.AppendChild(Of TableProperties)(props)

    For i = 0 To UBound(data, 1)
      Dim tr As New TableRow
      For j = 0 To UBound(data, 2)
        Dim tc As New TableCell
        tc.Append(New Paragraph(New Run(New Text(data(i, j)))))
        ' Assume you want columns that are automatically sized.
        tc.Append(New TableCellProperties(
          New TableCellWidth With {.Type = TableWidthUnitValues.Auto}))
        tr.Append(tc)
      Next
      table.Append(tr)
    Next
    doc.Body.Append(table)
    doc.Save()
  End Using
End Sub
public static void WDAddTable(string fileName, string[,] data)
{
  using (var document = WordprocessingDocument.Open(fileName, true))
  {

    var doc = document.MainDocumentPart.Document;

    Table table = new Table();

    TableProperties props = new TableProperties(
      new TableBorders(
        new TopBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new BottomBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new LeftBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new RightBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new InsideHorizontalBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        },
        new InsideVerticalBorder
        {
          Val = new EnumValue<BorderValues>(BorderValues.Single),
          Size = 12
        }));
    table.AppendChild<TableProperties>(props);

    for (var i = 0; i <= data.GetUpperBound(0); i++)
    {
      var tr = new TableRow();
      for (var j = 0; j <= data.GetUpperBound(1); j++)
      {
        var tc = new TableCell();
        tc.Append(new Paragraph(new Run(new Text(data[i, j]))));
        // Assume you want columns that are automatically sized.
        tc.Append(new TableCellProperties(
          new TableCellWidth { Type = TableWidthUnitValues.Auto }));
        tr.Append(tc);
      }
      table.Append(tr);
    }
    doc.Body.Append(table);
    doc.Save();
  }
}
读取

随此直观操作方法提供的示例介绍了用于将表插入到 Word 2007 或 Word 2010 文档中的代码。若要使用该示例,必须安装 Open XML SDK 2.0(可通过"浏览"一节中列出的链接获得)。该示例还使用作为 Open XML SDK 2.0 的代码示例集的一部分包含的代码。"浏览"一节还包括指向完整代码示例集的链接,但您无需下载并安装代码示例即可使用该示例。

示例应用程序只显示一些 Open XML SDK 2.0 提供的可用属性,您在创建 Word 表时可以与这些属性进行交互。有关详细信息,请参阅随 Open XML SDK 2.0 Productivity Tool 提供的文档:单击应用程序窗口左下角的"Open XML SDK 文档"选项卡,然后搜索要研究的类。首先查看 TableProperties 和 TableCellProperties 类。尽管该文档当前不包含代码示例,但借助此处所示的示例和文档,您应能成功修改示例应用程序。

观看

观看视频

观看视频(该链接可能指向英文页面) | 时长:00:20:29

单击以获取代码

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

浏览

关于作者
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)的合著者。