Generating Documents with Headers and Footers in Word 2007 by Using the Open XML SDK 2.0 for Microsoft Office

Summary: Learn how to use the Open XML Software Development Kit 2.0 for Microsoft Office to programmatically create Word 2007 documents that contain headers and footers. (11 printed pages)

Office Visual How To

Applies to: 2007 Microsoft Office System, Microsoft Office Word 2007, Open XML SDK 2.0 for Microsoft Office

Joel Krist, iSoftStone

August 2009

Overview

The Open XMLSoftware Development Kit 2.0 for Microsoft Office makes it possible to create and manipulate Microsoft Office Word 2007, Microsoft Office Excel 2007, and Microsoft Office PowerPoint 2007 documents programmatically via the Open XML formats. The typesafe classes included with the SDK provide a layer of abstraction between the developer and the Open XML formats, simplifying the process of working with Office 2007 documents and enabling the creation of complex document solutions.

The sample code in this visual how-to article shows how to programmatically create a Word 2007 document that contains headers and footers. The code uses the HeaderPart, FooterPart, HeaderReference, FooterReference, and EvenAndOddHeaders classes in the Open XML SDK 2.0 for Microsoft Office to create the required document parts.

See It Video startup screen

Watch the Video

Length: 06:50 | Size: 9.37 MB | Type: WMV file

Code It | Read It | Explore It

Code It

Download the sample code

This visual how-to article presents a solution that creates a Word 2007 document that contains different first, odd, and even page headers and footers. The document contains five pages, each separated by a hard page break, to illustrate the different headers and footers.

To illustrate how to create a Word 2007 document programmatically that contains headers and footers, this section walks through the following steps:

  1. Creating a Windows console application solution in Visual Studio 2008.

  2. Adding references to the DocumentFormat.OpenXml and WindowsBase assemblies.

  3. Adding the sample code to the solution.

Creating a Windows Console Application in Visual Studio 2008

This visual how-to article uses a Windows console application to provide the framework for the sample code. However, you could use the same approach that is illustrated here with other application types as well.

To create a Windows Console Application in Visual Studio 2008

  1. Start Microsoft Visual Studio 2008.

  2. On the File menu, point to New, and then click Project.

  3. In the New Project dialog box select the Visual C# Windows type in the Project types pane.

  4. Select Console Application in the Templates pane, and then name the project WordHeaderFooter.

    Figure 1. Create new solution in the New Project dialog box

    Create new solution in the New Project dialog box

     

  5. Click OK to create the solution.

Adding References to the DocumentFormat.OpenXml and WindowsBase Assemblies

The sample code uses the classes and enumerations that are in the DocumentFormat.OpenXml.dll assembly that is installed with the Open XML SDK 2.0 for Microsoft Office. To add the reference to the assembly in the following steps or to build the sample code that accompanies this visual how-to, you must first download and install the Open XML SDK 2.0 for Microsoft Office so that the assembly is available.

To add References to the DocumentFormat.OpenXml and WindowsBase Assemblies

  1. Add a reference to the DocumentFormat.OpenXml assembly by doing the following:

    1. On the Project menu in Visual Studio, click Add Reference to open the Add Reference dialog box.

    2. Select the .NET tab, scroll down to DocumenFormat.OpenXml, select it, and then click OK.

      Figure 2. Add Reference to DocumentFormat.OpenXML

      Add Reference to DocumentFormat.OpenXml

       

  2. The classes in the DocumentFormat.OpenXml assembly use the System.IO.Packaging.Package class that is defined in the WindowsBase assembly. Add a reference to the WindowsBase assembly by doing the following:

    1. On the Project menu in Visual Studio, click Add Reference to open the Add Reference dialog box.

    2. Select the .NET tab, scroll down to WindowsBase, select it, and then click OK.

      Figure 3. Add Reference to WindowsBase

      Add Reference to WindowsBase

       

Adding the Sample Code to the Solution

Replace the contents of the Program.cs source file with the following code.

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

class Program
{
    static void Main(string[] args)
    {
        string documentPath = @"C:\Temp\HeaderFooterDocument.docx";

        using (WordprocessingDocument package =
            WordprocessingDocument.Create(
            documentPath, WordprocessingDocumentType.Document))
        {
            AddParts(package);
        }
    }

    private static void AddParts(WordprocessingDocument parent)
    {
        var mainDocumentPart = parent.AddMainDocumentPart();
            
        GenerateMainDocumentPart().Save(mainDocumentPart);

        var documentSettingsPart =
            mainDocumentPart.AddNewPart
            <DocumentSettingsPart>("rId1");
            
        GenerateDocumentSettingsPart().Save(documentSettingsPart);

        var firstPageHeaderPart =
            mainDocumentPart.AddNewPart<HeaderPart>("rId2");
            
        GeneratePageHeaderPart(
            "First page header").Save(firstPageHeaderPart);

        var firstPageFooterPart =
            mainDocumentPart.AddNewPart<FooterPart>("rId3");
            
        GeneratePageFooterPart(
            "First page footer").Save(firstPageFooterPart);

        var evenPageHeaderPart =
            mainDocumentPart.AddNewPart<HeaderPart>("rId4");
            
        GeneratePageHeaderPart(
            "Even page header").Save(evenPageHeaderPart);

        var evenPageFooterPart =
            mainDocumentPart.AddNewPart<FooterPart>("rId5");
            
        GeneratePageFooterPart(
            "Even page footer").Save(evenPageFooterPart);

        var oddPageheaderPart =
            mainDocumentPart.AddNewPart<HeaderPart>("rId6");
            
        GeneratePageHeaderPart(
            "Odd page header").Save(oddPageheaderPart);

        var oddPageFooterPart =
            mainDocumentPart.AddNewPart<FooterPart>("rId7");
            
        GeneratePageFooterPart(
            "Odd page footer").Save(oddPageFooterPart);
    }

    private static Document GenerateMainDocumentPart()
    {
        var element =
            new Document(
                new Body(
                    new Paragraph(
                        new Run(
                            new Text("Page 1 content"))
                    ),
                    new Paragraph(
                        new Run(
                            new Break() { Type = BreakValues.Page })
                    ),
                    new Paragraph(
                        new Run(
                            new LastRenderedPageBreak(),
                            new Text("Page 2 content"))
                    ),
                    new Paragraph(
                        new Run(
                            new Break() { Type = BreakValues.Page })
                    ),
                    new Paragraph(
                        new Run(
                            new LastRenderedPageBreak(),
                            new Text("Page 3 content"))
                    ),
                    new Paragraph(
                        new Run(
                            new Break() { Type = BreakValues.Page })
                    ),
                    new Paragraph(
                        new Run(
                            new LastRenderedPageBreak(),
                            new Text("Page 4 content"))
                    ),
                    new Paragraph(
                        new Run(
                            new Break() { Type = BreakValues.Page })
                    ),
                    new Paragraph(
                        new Run(
                            new LastRenderedPageBreak(),
                            new Text("Page 5 content"))
                    ),
                    new SectionProperties(
                        new HeaderReference()
                        {
                            Type = HeaderFooterValues.First,
                            Id = "rId2"
                        },
                        new FooterReference()
                        {
                            Type = HeaderFooterValues.First,
                            Id = "rId3"
                        },
                        new HeaderReference()
                        {
                            Type = HeaderFooterValues.Even,
                            Id = "rId4"
                        },
                        new FooterReference()
                        {
                            Type = HeaderFooterValues.Even,
                            Id = "rId5"
                        },
                        new HeaderReference()
                        {
                            Type = HeaderFooterValues.Default,
                            Id = "rId6"
                        },
                        new FooterReference()
                        {
                            Type = HeaderFooterValues.Default,
                            Id = "rId7"
                        },
                        new PageMargin()
                        {
                            Top = 1440,
                            Right = (UInt32Value)1440UL,
                            Bottom = 1440,
                            Left = (UInt32Value)1440UL,
                            Header = (UInt32Value)720UL,
                            Footer = (UInt32Value)720UL,
                            Gutter = (UInt32Value)0UL
                        },
                        new TitlePage()
                    )));

        return element;
    }

    private static Footer GeneratePageFooterPart(string FooterText)
    {
        var element =
            new Footer(
                new Paragraph(
                    new ParagraphProperties(
                        new ParagraphStyleId() { Val = "Footer" }),
                    new Run(
                        new Text(FooterText))
                ));

        return element;
    }

    private static Header GeneratePageHeaderPart(string HeaderText)
    {
        var element =
            new Header(
                new Paragraph(
                    new ParagraphProperties(
                        new ParagraphStyleId() { Val = "Header" }),
                    new Run(
                        new Text(HeaderText))
                ));

        return element;
    }

    private static Settings GenerateDocumentSettingsPart()
    {
        var element =
            new Settings(new EvenAndOddHeaders());

        return element;
    }
}

Build and run the solution in Visual Studio by pressing CTRL+F5. When you build and run the sample code, it creates a document named HeaderFooterDocument.docx in the C:\Temp folder. To change the name or location of the document modify the sample code and change the value of the documentPath variable in the Main method.

Read It

The sample code in this visual how-to article illustrates how to create a Word 2007 document that contains headers and footers. This section uses code snippets from the Code It section to describe the approach to the solution.

The code first creates a WordprocessingDocument package via the WordprocessingDocument.Create method. It then calls the AddParts helper method to add the document parts needed to support the headers and footers.

using (WordprocessingDocument package =
    WordprocessingDocument.Create(documentPath,
        WordprocessingDocumentType.Document))
{
    AddParts(package);
}

The AddParts method calls helper methods to add the main document and document settings parts to the package.

var mainDocumentPart = parent.AddMainDocumentPart();
GenerateMainDocumentPart().Save(mainDocumentPart);

var documentSettingsPart =
    mainDocumentPart.AddNewPart<DocumentSettingsPart>("rId1");
GenerateDocumentSettingsPart().Save(documentSettingsPart);

The main document part that the GenerateMainDocumentPart method creates contains five pages, each seperated by a hard page break.

new Paragraph(
    new Run(
        new Text("Page 1 content"),
        new Break() { Type = BreakValues.Page })),
new Paragraph(
    new Run(
        new LastRenderedPageBreak(),
        new Text("Page 2 content"),
        new Break() { Type = BreakValues.Page })),
new Paragraph(
    new Run(
        new LastRenderedPageBreak(),
        new Text("Page 3 content"),
        new Break() { Type = BreakValues.Page })),
new Paragraph(
    new Run(
        new LastRenderedPageBreak(),
        new Text("Page 4 content"),
        new Break() { Type = BreakValues.Page })),
new Paragraph(
    new Run(
        new LastRenderedPageBreak(),
        new Text("Page 5 content")))

The main document part also contains first, even, and odd page header and footer settings.

new SectionProperties(
    new HeaderReference()
        { Type = HeaderFooterValues.First,
          Id = "rId2" },
    new FooterReference()
        { Type = HeaderFooterValues.First,
          Id = "rId3" },
    new HeaderReference()
        { Type = HeaderFooterValues.Even,
          Id = "rId4" },
    new FooterReference()
        { Type = HeaderFooterValues.Even,
          Id = "rId5" },
    new HeaderReference()
        { Type = HeaderFooterValues.Default,
          Id = "rId6" },
    new FooterReference()
        { Type = HeaderFooterValues.Default,
          Id = "rId7" },
    new PageMargin()
        { Top = 1440,
          Right = (UInt32Value)1440UL,
          Bottom = 1440,
          Left = (UInt32Value)1440UL,
          Header = (UInt32Value)720UL,
          Footer = (UInt32Value)720UL,
          Gutter = (UInt32Value)0UL },
    new TitlePage()
)

The document settings part that the GenerateDocumentSettingsPart method created specifies separate headers for even and odd pages in the document.

private static Settings GenerateDocumentSettingsPart()
{
    var element =
        new Settings(new EvenAndOddHeaders());

    return element;
}

After generating the main document and document settings parts, the AddParts method adds header and footer parts to the main document. The relationship IDs specified for the header and footer parts match the relationship IDs of the header and footer references added in the GenerateMainDocumentPart method.

var firstPageHeaderPart =
    mainDocumentPart.AddNewPart<HeaderPart>("rId2");

GeneratePageHeaderPart(
    "First page header").Save(firstPageHeaderPart);

var firstPageFooterPart =
    mainDocumentPart.AddNewPart<FooterPart>("rId3");

GeneratePageFooterPart(
    "First page footer").Save(firstPageFooterPart);

var evenPageHeaderPart =
    mainDocumentPart.AddNewPart<HeaderPart>("rId4");

GeneratePageHeaderPart(
    "Even page header").Save(evenPageHeaderPart);

var evenPageFooterPart =
    mainDocumentPart.AddNewPart<FooterPart>("rId5");

GeneratePageFooterPart(
    "Even page footer").Save(evenPageFooterPart);

var oddPageheaderPart =
    mainDocumentPart.AddNewPart<HeaderPart>("rId6");

GeneratePageHeaderPart(
    "Odd page header").Save(oddPageheaderPart);

var oddPageFooterPart =
    mainDocumentPart.AddNewPart<FooterPart>("rId7");

GeneratePageFooterPart(
    "Odd page footer").Save(oddPageFooterPart);

The GeneratePageFooterPart and GeneratePageHeaderPart methods called by the AddParts method when adding the header and footer parts to the main document part create Footer and Header elements that contain a single paragraph that displays a line of text.

private static Footer GeneratePageFooterPart(string FooterText)
{
    var element =
        new Footer(
            new Paragraph(
                new ParagraphProperties(
                    new ParagraphStyleId() { Val = "Footer" }),
                new Run(
                    new Text(FooterText))
            ));

    return element;
}

private static Header GeneratePageHeaderPart(string HeaderText)
{
    var element =
        new Header(
            new Paragraph(
                new ParagraphProperties(
                    new ParagraphStyleId() { Val = "Header" }),
                new Run(
                    new Text(HeaderText))
            ));

    return element;
}
NoteNote

When you use the Open XML SDK 2.0 for Microsoft Office to create a document-generation solution, it is best practice to create a template document first, and then use DocumentReflector, a tool that comes with the SDK. DocumentReflector can generate C# code that uses the SDK typesafe classes to reproduce your template document and the functionality that it contains. You can then use that code to help you add functionality or to help you understand the Open XML document parts and relationships that are required to implement a specific document feature. For more information about best practices and the Open XML SDK 2.0 for Microsoft Office, see Erika Ehrli's blog entry Getting Started Best Practices.

Explore It