How to: Replace the Header in a Word 2007 Document by Using the Open XML API

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The Office Open XML Package specification defines a set of XML files that contain the content and define the relationships for all of the document parts stored in a single package. These packages combine the document parts that comprise the document files for Microsoft® Office Excel® 2007, Microsoft Office PowerPoint® 2007, and Microsoft Office Word 2007. The Open XML object model allows you to create packages and manipulate the files that comprise the packages. This topic walks through the code and steps to replace the header in an Office Open XML package in Office Word 2007, although the steps are the same for each of the three 2007 Microsoft Office system programs that support the Office Open XML Format.

NoteNote

The code samples in this topic are in Microsoft Visual Basic® .NET and Microsoft Visual C#®. You can use them in an add-in created in Microsoft Visual Studio® 2008. For more information about how to create an add-in in Visual Studio 2008, see Getting Started with the Open XML Format SDK 1.0.

Replacing the Header in a Document

In the following code, you remove the header part in a document and replace it with a new document part containing custom XML from an external file.

Public Sub WDAddHeader(ByVal docName As String, ByVal headerContent As Stream)
   '  Given a document name, and a stream containing valid header content,
   '  add the stream content as a header in the document and remove the original headers.
   Const wordmlNamespace As String = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
   Const relationshipNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
   Dim wdDoc As WordprocessingDocument = WordprocessingDocument.Open(docName, True)

   Using (wdDoc)
      ' Delete the existing header part.
      wdDoc.MainDocumentPart.DeleteParts(wdDoc.MainDocumentPart.HeaderParts)

      '  Create a new header part.
      Dim headerPart As HeaderPart = wdDoc.MainDocumentPart.AddNewPart(Of HeaderPart)()
      Dim rId As String = wdDoc.MainDocumentPart.GetIdOfPart(headerPart)
      Dim headerDoc As XmlDocument = New XmlDocument
      headerContent.Position = 0
      headerDoc.Load(headerContent)

      '  Write the header out to its document part.
      headerDoc.Save(headerPart.GetStream)

      '  Manage namespaces to perform Xml XPath queries.
      Dim nt As NameTable = New NameTable
      Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
      nsManager.AddNamespace("w", wordmlNamespace)

      '  Get the document part from the package.
      '  Load the XML in the part into an XmlDocument instance.
      Dim xdoc As XmlDocument = New XmlDocument(nt)
      xdoc.Load(wdDoc.MainDocumentPart.GetStream)

      '  Find the node containing the document layout.
      Dim targetNodes As XmlNodeList = xdoc.SelectNodes("//w:sectPr", nsManager)
      For Each targetNode As XmlNode In targetNodes
         '  Delete any existing references to headers.
         Dim headerNodes As XmlNodeList = targetNode.SelectNodes("./w:headerReference", nsManager)
         For Each headerNode As System.Xml.XmlNode In headerNodes
            targetNode.RemoveChild(headerNode)
         Next
         '  Create the new header reference node.
         Dim node As XmlElement = xdoc.CreateElement("w:headerReference", wordmlNamespace)
         Dim attr As XmlAttribute = node.Attributes.Append(xdoc.CreateAttribute("r:id", relationshipNamespace))
         attr.Value = rId
         node.Attributes.Append(attr)
         targetNode.InsertBefore(node, targetNode.FirstChild)
      Next

      '  Save the document XML back to its document part.
      xdoc.Save(wdDoc.MainDocumentPart.GetStream(FileMode.Create))
   End Using
End Sub
public static void WDAddHeader(string docName, Stream headerContent)
{
   //  Given a document name, and a stream containing valid header content,
   //  add the stream content as a header in the document and remove the original headers.

   const string wordmlNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
   const string relationshipNamespace = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";

   using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(docName, true))
   {
      // Delete the existing header part.
      wdDoc.MainDocumentPart.DeleteParts(wdDoc.MainDocumentPart.HeaderParts);

      //  Create a new header part.
      HeaderPart headerPart = wdDoc.MainDocumentPart.AddNewPart<HeaderPart>();
      string rId = wdDoc.MainDocumentPart.GetIdOfPart(headerPart);                
      XmlDocument headerDoc = new XmlDocument();
      headerContent.Position = 0;
      headerDoc.Load(headerContent);

      //  Write the header out to its document part.
      headerDoc.Save(headerPart.GetStream());

      //  Manage namespaces to perform XML XPath queries.
      NameTable nt = new NameTable();
      XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
      nsManager.AddNamespace("w", wordmlNamespace);

      //  Get the document part from the package.
      //  Load the XML in the part into an XmlDocument instance.
      XmlDocument xdoc = new XmlDocument(nt);
      xdoc.Load(wdDoc.MainDocumentPart.GetStream());

      //  Find the node containing the document layout.
      XmlNodeList targetNodes = xdoc.SelectNodes("//w:sectPr", nsManager);
      foreach (XmlNode targetNode in targetNodes)
      {
         //  Delete any existing references to headers.
         XmlNodeList headerNodes = targetNode.SelectNodes("./w:headerReference", nsManager);
         foreach (System.Xml.XmlNode headerNode in headerNodes)
         {
            targetNode.RemoveChild(headerNode);
         }

         //  Create the new header reference node.
         XmlElement node = xdoc.CreateElement("w:headerReference", wordmlNamespace);
         XmlAttribute attr = node.Attributes.Append(xdoc.CreateAttribute("r:id", relationshipNamespace));
         attr.Value = rId;
         node.Attributes.Append(attr);
         targetNode.InsertBefore(node, targetNode.FirstChild);
      }

      //  Save the document XML back to its document part.
      xdoc.Save(wdDoc.MainDocumentPart.GetStream(FileMode.Create));
   }
}

To remove the header part in a document and replace it with a new document part

  1. First, pass in parameters representing the path to and the name of the source Word 2007 document and the XML that defines the header that replaces the existing header in the document.

  2. Then, open the document as a WordprocessingDocument object.

  3. Next, delete the existing header parts in the document and then create a blank header part.

  4. Then, create an XML document that is a temporary holder for the XML that describes the replacement header.

    The remaining code searches for the references to the header parts that you just deleted in the main document part by using XPath queries for the appropriate namespaces, deletes them, and inserts references to the new header part.

  5. Finally, the XML is saved back to the main document part.