65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Open XML Format SDK 创建 Word 2007 文档

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (24投票s)

2009年5月24日

CPOL

5分钟阅读

viewsIcon

170192

downloadIcon

4670

一篇简单的“入门”文章,展示了使用 Open XML Format SDK 2.0 CTP 创建 Word 2007 (docx) 文档的基础知识。

open_xml_dsk_dockx_helloworld_witharrows_small.jpg

引言

2009 年 4 月,Microsoft 发布了 Open XML Format SDK 2.0 CTP。Open XML 是一个开放的 ECMA 376 标准,也被批准为 ISO/IEC 29500 标准,它定义了一组用于表示电子表格、图表、演示文稿和文字处理文档的 XML 架构。Microsoft Office Word 2007、Excel 2007 和 PowerPoint 2007 都使用 Open XML 作为默认文件格式。该 SDK 提供了用于轻松创建、修改和验证 Open XML 文件的功能。在本文中,我将重点介绍如何使用 Open XML Format SDK 2.0 CTP 创建 Word 2007 (docx) 文档。

Open XML Format SDK 提供了一个简单的 API,允许使用 .NET 平台提供的可用语言之一来创建和操作 Open XML 文档。借助此 SDK,无需了解 XML 和 WordprocessingML 即可处理 Open XML 文档(尽管有时它非常有帮助)。该 SDK 通过允许您执行复杂操作(例如创建 Open XML Format 包(包括对内部文档、样式、主题等的轻松支持))或处理文本和格式(如添加和删除页眉、段落、表格、批注等)来简化您构建 Open XML Format 解决方案的过程,只需几行代码即可完成。

第一个应用程序(Open XML 中的“Hello World!”)

让我们从一个简单的任务开始:创建一个包含示例且广为人知的文本“Hello World!”的 Word 文档。对于熟悉 WordprocessingML 的人来说,我们将创建一个包含以下内容的文档:

<?xml version="1.0" encoding="utf-8"?> 
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
  <w:body> 
   <w:p> 
   <w:r> 
   <w:t>Hello World!</w:t> 
   </w:r> 
   </w:p> 
  </w:body> 
</w:document>

但问题是:如何在 Open XML Format SDK 中实现呢?

这很简单。首先,需要在项目中添加以下引用:

  • DocumentFormat.OpenXml
  • WindowsBase

下一步是向代码文件添加以下命名空间(作为 using):

  • DocumentFormat.OpenXml
  • DocumentFormat.OpenXml.Packaging
  • DocumentFormat.OpenXml.Wordprocessing

现在,我们来关注准备包含“Hello World”的 Word 文档的函数。

private void HelloWorld(string documentFileName) 
{ 
    // Create a Wordprocessing document. 
    using (WordprocessingDocument myDoc = 
           WordprocessingDocument.Create(documentFileName, 
                         WordprocessingDocumentType.Document)) 
    { 
        // Add a new main document part. 
        MainDocumentPart mainPart = myDoc.AddMainDocumentPart(); 
        //Create Document tree for simple document. 
        mainPart.Document = new Document(); 
        //Create Body (this element contains
        //other elements that we want to include 
        Body body = new Body(); 
        //Create paragraph 
        Paragraph paragraph = new Paragraph(); 
        Run run_paragraph = new Run(); 
        // we want to put that text into the output document 
        Text text_paragraph = new Text("Hello World!"); 
        //Append elements appropriately. 
        run_paragraph.Append(text_paragraph); 
        paragraph.Append(run_paragraph); 
        body.Append(paragraph); 
        mainPart.Document.Append(body); 
        // Save changes to the main document part. 
        mainPart.Document.Save(); 
    } 
}

上面的代码会创建一个 Word 文档文件(根据调用者的参数),其中包含一个带有文本“Hello World!”的段落。就像前面显示的 XML 一样,文本嵌入在 Run 元素中,该元素嵌入在 Paragraph 中,而 Paragraph 又添加到 bodydocument 中。

SaveFileDialog mySaveFileDialog=new SaveFileDialog(); 
mySaveFileDialog.Filter = "Word 2007 file (DOCX)|*.docx"; 
//save dialog display: 
if (mySaveFileDialog.ShowDialog() == DialogResult.OK) 
{ 
    //call creation of Hello World document 
    HelloWorld(mySaveFileDialog.FileName); 
    // let's open this document in Word: 
    Process.Start(mySaveFileDialog.FileName); 
}

Open XML SDK 中的样式

在上一节中,我们创建了一个简单的文档。字体和样式是默认的,但现在出现了一个问题:如何更改字体?如何更改字体大小?如何创建标题?答案(对于所有这些问题)都是样式(就像在 Word 中一样),但如何在 SDK 中实现呢?

让我们看一个创建包含两行的文档的示例。第一行将是段落标题(在本例中,字体为红色、粗体,字号为 28)。第二行将是标准段落。我已经描述了如何准备一个普通段落,所以让我们专注于第一行(根据我们的要求进行格式化)。

第一项任务是将样式定义部分(StyleDefinitionsPart)添加到文档中。它应该添加到主文档部分。

WordprocessingDocument myDoc = 
  WordprocessingDocument.Create(documentFileName, WordprocessingDocumentType.Document) 
MainDocumentPart mainPart = myDoc.AddMainDocumentPart(); 
StyleDefinitionsPart stylePart = mainPart.AddNewPart<StyleDefinitionsPart>();

现在,我们必须定义要使用的字体(红色、粗体,字号为 28)。

// we have to set the properties
RunProperties rPr = new RunProperties();
Color color = new Color() { Val = "FF0000" }; // the color is red
RunFonts rFont = new RunFonts();
rFont.Ascii = "Arial"; // the font is Arial
rPr.Append(color);
rPr.Append(rFont);
rPr.Append(new Bold()); // it is Bold
rPr.Append(new FontSize() { Val = 28 }); //font size (in 1/72 of an inch)

现在是定义样式的时候了。我们称之为“My Heading 1”,标识符是“MyHeading1”(此标识符将直接在 Word 文档中使用)。下面的示例代码说明了如何做到这一点。

//creation of a style
Style style = new Style();
style.StyleId = "MyHeading1"; //this is the ID of the style
style.Append(new Name() { Val = "My Heading 1" }); //this is name
// our style based on Normal style
style.Append(new BasedOn() { Val = "Heading1" });
// the next paragraph is Normal type
style.Append(new NextParagraphStyle() { Val = "Normal" });
style.Append(rPr);//we are adding properties previously defined

创建样式后,我们必须将其添加到样式文档中。

// we have to add style that we have created to the StylePart
stylePart.Styles = new Styles();
stylePart.Styles.Append(style);
stylePart.Styles.Save(); // we save the style part

上面的代码会在 WordprocessingML 中准备以下样式定义文件:

<?xml version="1.0" encoding="utf-8"?> 
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
    <w:style w:styleId="MyHeading1"> 
        <w:name w:val="My Heading 1" /> 
        <w:basedOn w:val="Heading1" /> 
        <w:next w:val="Normal" /> 
        <w:rPr> 
        <w:color w:val="FF0000" /> 
        <w:rFonts w:ascii="Arial" /> 
        <w:b /> 
        <w:sz w:val="28" /> 
        </w:rPr> 
    </w:style> 
</w:styles>

我们完成了与样式创建相关的任务;现在,我们必须将样式分配给选定的段落。为此,我们将使用 ParagraphProperties 类及其 ParagraphStyleId 属性。

Paragraph heading = new Paragraph();
Run heading_run = new Run();
Text heading_text = new Text("This is Heading");
ParagraphProperties heading_pPr = new ParagraphProperties();
// we set the style
heading_pPr.ParagraphStyleId = new ParagraphStyleId() { Val = "MyHeading1" };
heading.Append(heading_pPr);
heading_run.Append(heading_text);
heading.Append(heading_run);

上面的代码会在 WordprocessingML 中准备以下文档文件:

<?xml version="1.0" encoding="utf-8"?> 
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> 
    <w:body> 
        <w:p> 
            <w:pPr> 
            <w:pStyle w:val="MyHeading1" /> 
            </w:pPr> 
            <w:r> 
            <w:t>This is Heading</w:t> 
            </w:r> 
        </w:p> 
    </w:body> 
</w:document>

Open XML SDK 中的表格

在本节中,我将重点介绍如何使用 Open XML Format SDK 创建表格。得益于简单的 API,这就像前面显示的示例一样容易。要创建表格,我们必须使用 Table 类,在该类中嵌入 TableRowTableCell 元素。简单的示例代码如下所示。

Body body = new Body();
Table table = new Table(new TableRow(new TableCell(
  new Paragraph(new Run(new Text("Hello World!"))))));
body.Append(table);

在下面的示例中,我将展示如何创建一个包含“乘法表”(就像在学校里一样 :) )的简单文档。

乘法表

*

1

2

3

4

5

6

7

8

9

10

1

1

2

3

4

5

6

7

8

9

10

2

2

4

6

8

10

12

14

16

18

20

3

3

6

9

12

15

18

21

24

27

30

4

4

8

12

16

20

24

28

32

36

40

5

5

10

15

20

25

30

35

40

45

50

6

6

12

18

24

30

36

42

48

54

60

7

7

14

21

28

35

42

49

56

63

70

8

8

16

24

32

40

48

56

64

72

80

9

9

18

27

36

45

54

63

72

81

90

10

10

20

30

40

50

60

70

80

90

100

在本节的开头,有一个示例展示了如何准备最简单的表格。现在,我们将同样使用 TableTableCellTableRow 元素,但此外,我们还必须设置边框并在第一个单元格中跨越多列。

要设置边框,有必要为表格设置特殊属性。为此,我们必须使用 TablePropertiesTableBorders 类。

Table table = new Table();
TableProperties tblPr = new TableProperties();
TableBorders tblBorders = new TableBorders();
tblBorders.TopBorder = new TopBorder();
tblBorders.TopBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.BottomBorder = new BottomBorder();
tblBorders.BottomBorder.Val =new EnumValue<BorderValues>(  BorderValues.Single);
tblBorders.LeftBorder = new LeftBorder();
tblBorders.LeftBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.RightBorder = new RightBorder();
tblBorders.RightBorder.Val = new EnumValue<BorderValues>(BorderValues.Single);
tblBorders.InsideHorizontalBorder = new InsideHorizontalBorder();
tblBorders.InsideHorizontalBorder.Val = BorderValues.Single;
tblBorders.InsideVerticalBorder = new InsideVerticalBorder();
tblBorders.InsideVerticalBorder.Val = BorderValues.Single;
tblPr.Append(tblBorders);
table.Append(tblPr);

现在,让我们看一下第一行及其单元格。我们必须将 span 属性设置为跨越 11 列。为此,我们必须为该单元格(TableCellProperties)及其 GridSpan 属性设置特殊属性。

tr = new TableRow();
tc = new TableCell(new Paragraph(new Run(new Text("Multiplication table"))));
TableCellProperties tcp=new TableCellProperties();
GridSpan gridSpan=new GridSpan();
gridSpan.Val=11;
tcp.Append(gridSpan);
tc.Append(tcp);
tr.Append(tc);

最后,我们有以下函数:

public void HelloWorld_table(string docName)
{
  // Create a Wordprocessing document. 
  using (WordprocessingDocument myDoc = 
         WordprocessingDocument.Create(docName, 
                       WordprocessingDocumentType.Document))
  {
    // Add a new main document part. 
    MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
    //Create DOM tree for simple document. 
    mainPart.Document = new Document();
    Body body = new Body();
    Table table = new Table();
    TableProperties tblPr = new TableProperties();
    TableBorders tblBorders = new TableBorders();
    tblBorders.TopBorder = new TopBorder();
    tblBorders.TopBorder.Val = new EnumValue<bordervalues>(BorderValues.Single);
    tblBorders.BottomBorder = new BottomBorder();
    tblBorders.BottomBorder.Val =new EnumValue<bordervalues>(  BorderValues.Single);
    tblBorders.LeftBorder = new LeftBorder();
    tblBorders.LeftBorder.Val = new EnumValue<bordervalues>(BorderValues.Single);
    tblBorders.RightBorder = new RightBorder();
    tblBorders.RightBorder.Val = new EnumValue<bordervalues>(BorderValues.Single);
    tblBorders.InsideHorizontalBorder = new InsideHorizontalBorder();
    tblBorders.InsideHorizontalBorder.Val = BorderValues.Single;
    tblBorders.InsideVerticalBorder = new InsideVerticalBorder();
    tblBorders.InsideVerticalBorder.Val = BorderValues.Single;
    tblPr.Append(tblBorders);
    table.Append(tblPr);
    TableRow tr;
    TableCell tc;
    //first row - title
    tr = new TableRow();
    tc = new TableCell(new Paragraph(new Run(
                       new Text("Multiplication table"))));
    TableCellProperties tcp=new TableCellProperties();
    GridSpan gridSpan=new GridSpan();
    gridSpan.Val=11;
    tcp.Append(gridSpan);
    tc.Append(tcp);
    tr.Append(tc);
    table.Append(tr);
    //second row 
    tr = new TableRow();
    tc = new TableCell();
    tc.Append(new Paragraph(new Run(new Text("*"))));
    tr.Append(tc);
    for (int i = 1; i <= 10; i++)
    {
      tr.Append(new TableCell(new Paragraph(new Run(new Text(i.ToString())))));
    }
    table.Append(tr);
    for (int i = 1; i <= 10; i++)
    {
      tr = new TableRow();
      tr.Append(new TableCell(new Paragraph(new Run(new Text(i.ToString())))));
      for (int j = 1; j <= 10; j++)
      {
        tr.Append(new TableCell(new Paragraph(new Run(new Text((i*j).ToString())))));
      }
      table.Append(tr);
    }
    //appending table to body
    body.Append(table);
    // and body to the document
    mainPart.Document.Append(body);
    // Save changes to the main document part. 
    mainPart.Document.Save();
  }
}

上面的代码会在 WordprocessingML 中生成以下文档文件:

<?xml version="1.0" encoding="utf-8" ?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:tbl>
            <w:tblpr>
                <w:tblborders>
                    <w:top w:val="single" />
                    <w:left w:val="single" />
                    <w:bottom w:val="single" />
                    <w:right w:val="single" />
                    <w:insideh w:val="single" />
                    <w:insidev w:val="single" />
                </w:tblborders>
            </w:tblpr>
            <w:tr>
                <w:tc>
                    <w:p>
                        <w:r>
                            <w:t>Multiplication table</w:t>
                        </w:r>
                    </w:p>
                    <w:tcpr>
                        <w:gridspan w:val="11" />
                    </w:tcpr>
                </w:tc>
            </w:tr>
            <w:tr> 
            <w:tc>
                <w:p>
                    <w:r>
                        <w:t>*</w:t>
                    </w:r>
                </w:p>
            </w:tc> 
            <w:tc>
                <w:p>
                    <w:r>
                        <w:t>1</w:t>
                    </w:r>
                </w:p>
            </w:tc> 
            <!—- many cells and rows declarations --> 
            </w:tr>
        </w:tbl>
    </w:body>
</w:document>

摘要

我希望这篇简单的文章能对有兴趣使用 Open XML Format SDK 进行开发的开发人员有所帮助。我将在未来更新这篇文章,以展示更多关于该 SDK 和该格式的内容。波兰语版本可在 我的博客 上分部分查看。

历史

© . All rights reserved.