Click here to Skip to main content
15,868,016 members
Articles / Productivity Apps and Services / Microsoft Office

Creation of a Word 2007 document using the Open XML Format SDK

Rate me:
Please Sign up or sign in to vote.
4.92/5 (24 votes)
24 May 2009CPOL5 min read 164.3K   4.6K   72   22
A simple “getting started” article that shows the basis of creation of a Word 2007 (docx) document using the Open XML Format SDK 2.0 CTP.

open_xml_dsk_dockx_helloworld_witharrows_small.jpg

Introduction

On April 2009, Microsoft published the Open XML Format SDK 2.0 CTP. Open XML is an open ECMA 376 standard, and is also approved as the ISO/IEC 29500 standard that defines a set of XML schemas for representing spreadsheets, charts, presentations, and word processing documents. Microsoft Office Word 2007, Excel 2007, and PowerPoint 2007 all use Open XML as the default file format. This SDK provides the functionality for easy creation, modification, and verification of Open XML files. In this article, I want to focus on the creation of Word 2007 (docx) documents using the Open XML Format SDK 2.0 CTP.

The Open XML Format SDK provides a simple API that allows to create and manipulate Open XML documents using one of the available languages from the .NET platform. Thanks to this SDK, a knowledge about XML and WordprocessingML is not required to work on Open XML documents (however, sometimes it is very useful). The SDK makes it easier for you to build solutions using the Open XML Format by allowing you to perform complex operations, such as creating Open XML Format packages (including easy support for internal documents, styles, themes, etc ...), or working with text and formatting like adding and deleting headers, paragraphs, tables, comments, etc…, with just a few lines of code.

First Application ("Hello World!" in Open XML)

Let’s start from an easy task: creation of a Word document that contains a sample and well known text: "Hello World!". For those who are familiar with WordprocessingML, we are going to crate a document with the following content:

XML
<?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>

But the question is: how to do it in the Open XML Format SDK?

It is quite easy. At the beginning, it is required to add the following references to the project:

  • DocumentFormat.OpenXml
  • WindowsBase

The next step is adding the following namespaces (as using) to the code file:

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

Now focus on the function that prepares the Word document containing "Hello World":

C#
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(); 
    } 
}

The code above creates a Word Document file (according to the caller arguments), which contains a paragraph with the text: Hello World!”. Just like in the previously shown XML, the text is embedded inside the Run element, that is embedded in Paragraph, that is added to the body and to the document.

C#
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); 
}

Styles in Open XML SDK

In the previous section, we created a simple document. The font and style were default, but here comes the questions: How to change the font? How to change the size of the font? How to create a heading? The answer (for all of those questions) is styles (just like in Word), but how to do it in the SDK?

Let’s take a look at the example of creation of a document that will consist of two lines. The first line will be the heading of the paragraph (in this example, the font is red, bold, and the height is 28). The second one will be a standard paragraph. I have already described how to prepare an ordinary paragraph, so let’s focus on the first line (formatted according to our requirements).

The first task is the addition of the style definition part (StyleDefinitionsPart) to the document. It should be added to the main document part:

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

Now, we have to define the font that we want to use (red, bold, and the height is 28):

C#
// 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)

Now, it is time for the style definition. Let’s call it "My Heading 1", the identifier is "MyHeading1" (this identifier will be used directly in the Word document). The sample code below illustrates how to do it:

C#
//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

After the creation of the style, we have to add this to the style document:

C#
// 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

The code above prepares the following style definition file in WordprocessingML:

XML
<?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>

We have finished the work that refers to the style creation; now, we have to assign the style to the selected paragraph. To do it, we will use the ParagraphProperties class and its ParagraphStyleId property:

C#
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);

The code above prepares the following document file in WordprocessingML:

XML
<?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>

Tables in Open XML SDK

In this section, I want to focus on the creation of tables using the Open XML Format SDK. Thanks to the simple API, it is easy as the examples shown before. To create a table, we have to use the Table class in which we embed the TableRow and TableCell elements. The simple example presents the code below:

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

In the following example, I will show how to create a simple document that contains the "Multiplication table" (just like in school :) ):

Multiplication 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

At the beginning of this section, there was an example that showed how to prepare the simplest table. Now, we will also use the Table, TableCell, and TableRow elements, but additionally, we have to set the borders and span multiple columns in the first cell.

To set the borders, it is necessary to set special properties for the table. To do it, we have to use the TableProperties and TableBorders classes:

C#
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);

Now, let’s take a look at the first row and its cell. We have to set the span attribute to span 11 columns. To do it, we have to set the special properties for this cell (TableCellProperties) and its GridSpan property.

C#
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);

Finally, we have the following function:

C#
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();
  }
}

The code above produces the following document file in WordprocessingML:

XML
<?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>

Summary

I hope that this simple article will be useful for developers that are interested in development using the Open XML Format SDK. I am going to update this article in future to show more about this SDK and this format. The Polish version is available in parts at my blog.

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Poland Poland

I am software developer and architect. I am interested in real-time systems programming, communication systems and new technologies.


For readers from Poland I suggest to visit my blog: http://maciej-progtech.blogspot.com/ to find interesting resources.


Comments and Discussions

 
GeneralThank you! Pin
Shine Tyler26-Jul-16 21:54
Shine Tyler26-Jul-16 21:54 
QuestionCouldn't open .docx file using open office? Pin
Member 1230173911-Apr-16 1:04
Member 1230173911-Apr-16 1:04 
QuestionHow can I add a picture inside a table cell? Pin
cas20007-Aug-15 6:24
cas20007-Aug-15 6:24 
QuestionText Box Pin
Member 109081218-Jul-14 4:38
Member 109081218-Jul-14 4:38 
Questionvery helpful to start Pin
KyurShah26-Mar-14 1:11
KyurShah26-Mar-14 1:11 
QuestionNeed Information for running the source code Pin
Member 104440934-Dec-13 0:31
Member 104440934-Dec-13 0:31 
QuestionError creating new instance of Wordprocessing Document Pin
AshWebb15-May-13 2:52
AshWebb15-May-13 2:52 
QuestionHow to Create bulletted List using openXML in C# Pin
jintopaul 13-Mar-13 23:47
jintopaul 13-Mar-13 23:47 
QuestionSubscript and Superscript text in a paragraph Pin
Member 901074324-Jul-12 19:36
Member 901074324-Jul-12 19:36 
AnswerRe: Subscript and Superscript text in a paragraph Pin
zzrookie2-Aug-14 0:06
zzrookie2-Aug-14 0:06 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey16-Mar-12 22:56
professionalManoj Kumar Choubey16-Mar-12 22:56 
GeneralTOC problems Pin
Thomas C. Abruzzo15-Apr-11 5:13
Thomas C. Abruzzo15-Apr-11 5:13 
GeneralRe: TOC problems Pin
Johnny Glenn26-Mar-12 22:40
Johnny Glenn26-Mar-12 22:40 
OpenXML SDK does not provide a functionality to update a TOC because that would require a layout engine (a paginator) which OpenXML SDK does not have and, probably, never will.

You can mark TOC field as dirty, so when you open a document with MS Word it will automatically be updated, but this usually opens some dialog window which is not user (client) friendly.

--
C# create Word with C# / VB.NET Word component.
QuestionIs there any way to have a code generated document inherit the styles and themes that Word's GUI has by default? Pin
DannyStaten29-Mar-11 19:25
DannyStaten29-Mar-11 19:25 
GeneralRTF to WordML Pin
Ravi Sant10-Feb-11 4:41
Ravi Sant10-Feb-11 4:41 
GeneralRe: RTF to WordML Pin
Maciej Zbrzezny10-Feb-11 6:24
Maciej Zbrzezny10-Feb-11 6:24 
GeneralMy vote of 5 Pin
zitun18-Jan-11 11:07
zitun18-Jan-11 11:07 
GeneralThank you Pin
db.moh23-Aug-10 0:47
db.moh23-Aug-10 0:47 
GeneralThank you Pin
emmilely15-Apr-10 9:25
emmilely15-Apr-10 9:25 
GeneralHello World with styles Pin
fhunth5-Apr-10 11:32
fhunth5-Apr-10 11:32 
GeneralGreat piece of work Pin
kalyankrishna125-Nov-09 7:35
kalyankrishna125-Nov-09 7:35 
GeneralRe: Great piece of work Pin
Maciej Zbrzezny2-Dec-09 10:21
Maciej Zbrzezny2-Dec-09 10:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.