0 out of 4 rated this helpful - Rate this topic

How to: Replace the Header in a Word Processing Document

This topic shows how to use the classes in the Open XML SDK 2.0 for Microsoft Office to replace the header in word processing document programmatically.

To use the sample code in this topic, you must install the Open XML SDK 2.0, available from this link. You must explicitly reference the following assemblies in your project:

  • WindowsBase

  • DocumentFormat.OpenXml (installed by the Open XML SDK)

You must also use the following using directives or Imports statements to compile the code in this topic.

using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

In this example. you are going to delete the header part from the target file and create another header part. You are also going to delete the reference to the existing header and create a reference to the new header. Therefore it is useful to familarize yourself with headers and the header reference element. The following information from the ISO/IEC 29500 specification introduces the header reference element.

headerReference (Header Reference)

This element specifies a single header which shall be associated with the current section in the document. This header shall be referenced via the id attribute, which specifies an explicit relationship to the appropriate Header part in the WordprocessingML package.

If the relationship type of the relationship specified by this element is not http://schemas.openxmlformats.org/officeDocument/2006/header, is not present, or does not have a TargetMode attribute value of Internal, then the document shall be considered non-conformant.

Within each section of a document there may be up to three different types of headers:

  • First page header

  • Odd page header

  • Even page header

The header type specified by the current headerReference is specified via the type attribute.

If any type of header is omitted for a given section, then the following rules shall apply.

  • If no headerReference for the first page header is specified and the titlePg element is specified, then the first page header shall be inherited from the previous section or, if this is the first section in the document, a new blank header shall be created. If the titlePg element is not specified, then no first page header shall be shown, and the odd page header shall be used in its place.

  • If no headerReference for the even page header is specified and the evenAndOddHeaders element is specified, then the even page header shall be inherited from the previous section or, if this is the first section in the document, a new blank header shall be created. If the evenAndOddHeaders element is not specified, then no even page header shall be shown, and the odd page header shall be used in its place.

  • If no headerReference for the odd page header is specified then the even page header shall be inherited from the previous section or, if this is the first section in the document, a new blank header shall be created.

[Example: Consider a three page document with different first, odd, and even page header defined as follows:

Three page document with different headers


This document defines three headers, each of which has a relationship from the document part with a unique relationship ID, as shown in the following packaging markup:

<Relationships xmlns=http://schemas.openxmlformats.org/package/2006/relationships>
  …
  <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml" />
  <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header2.xml" />
  <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header3.xml" />
  …
</Relationships>

These relationships are then referenced in the section's properties using the following WordprocessingML:

<w:sectPr>
  …
  <w:headerReference r:id="rId3" w:type="first" />
  <w:headerReference r:id="rId5" w:type="default" />
  <w:headerReference r:id="rId2" w:type="even" />
  …
</w:sectPr>

The resulting section shall use the header part with relationship id rId3 for the first page, the header part with relationship id rId2 for all subsequent even pages, and the header part with relationship id rId5 for all subsequent odd pages. end example]

© ISO/IEC29500: 2008.

The following code example shows how to replace the header in a word processing document with the header from another word processing document. To call the method, AddHeaderFromTo, you can use the following code segment as an example.

string filepathFrom = @"C:\Users\Public\Documents\Word15a.docx";
string filepathTo=@"C:\Users\Public\Documents\Word15b.docx";
AddHeaderFromTo(filepathFrom,  filepathTo);

Following is the complete sample code in both C# and Visual Basic.

public static void AddHeaderFromTo(string filepathFrom, string filepathTo)
{
    // Replace header in target document with header of source document.
    using (WordprocessingDocument 
        wdDoc = WordprocessingDocument.Open(filepathTo, true))
    {
        MainDocumentPart mainPart = wdDoc.MainDocumentPart;
        
        // Delete the existing header part.
        mainPart.DeleteParts(mainPart.HeaderParts);

        // Create a new header part.
        DocumentFormat.OpenXml.Packaging.HeaderPart headerPart = 
    mainPart.AddNewPart<HeaderPart>();
        
        // Get Id of the headerPart.
        string rId = mainPart.GetIdOfPart(headerPart);
        
        // Feed target headerPart with source headerPart.
        using (WordprocessingDocument wdDocSource = 
            WordprocessingDocument.Open(filepathFrom, true))
        {
            DocumentFormat.OpenXml.Packaging.HeaderPart firstHeader =
    wdDocSource.MainDocumentPart.HeaderParts.FirstOrDefault();

                wdDocSource.MainDocumentPart.HeaderParts.FirstOrDefault();

            if (firstHeader != null)
            {
                headerPart.FeedData(firstHeader.GetStream());
            }
        }

        // Get SectionProperties and Replace HeaderReference with new Id.
        IEnumerable<DocumentFormat.OpenXml.Wordprocessing.SectionProperties> sectPrs = 
    mainPart.Document.Body.Elements<SectionProperties>();
        foreach (var sectPr in sectPrs)
        {
            // Delete existing references to headers.
            sectPr.RemoveAllChildren<HeaderReference>();

            // Create the new header reference node.
            sectPr.PrependChild<HeaderReference>(new HeaderReference() { Id = rId });
        }    
    }
}
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Mistake in the Sample
Once I make the correction suggested by Ankush, the target document's header is removed and the code no longer results in a corrupted target document. However, the source document's header is not copied to the target document. I am also trying to copy a header that contains images.

Any help would be greatly appreciated!


[tfl - 02 04 12] Hi - and thanks for your post. Community content is not the appropriate place for technical support queries. Instead, you should visit the MSDN Forums at http://forums.microsoft.com/MSDN, where such posts are welcomed and where you stand a much better chance of getting your query resolved. Sorry if that's not the answer you wanted to hear.

how to get it to work whit Image?
hi has any body got this to work with image in the header


[tfl - 02 04 12] Hi - and thanks for your post. Community content is not the appropriate place for technical support queries. Instead, you should visit the MSDN Forums at http://forums.microsoft.com/MSDN, where such posts are welcomed and where you stand a much better chance of getting your query resolved. Sorry if that's not the answer you wanted to hear.

copy a content controle
Hi, do anybody know a easy way to copy the content from a RTF ContentControle i one doc to a RTF content Controle in a other doc?

[tfl - 02 04 12] Hi - and thanks for your post. Community content is not the appropriate place for technical support queries. Instead, you should visit the MSDN Forums at http://forums.microsoft.com/MSDN, where such posts are welcomed and where you stand a much better chance of getting your query resolved. Sorry if that's not the answer you wanted to hear.

any body find a solution for the image problem?
hi if any of you have solved the image problem, pleas let me know, I am trying but no lock so fare :-(
best Morten


[tfl - 02 04 12] Hi - and thanks for your post. Community content is not the appropriate place for technical support queries. Instead, you should visit the MSDN Forums at http://forums.microsoft.com/MSDN, where such posts are welcomed and where you stand a much better chance of getting your query resolved. Sorry if that's not the answer you wanted to hear.

To Copy image in header
to copy headers with images
Using wdDocSource As WordprocessingDocument = WordprocessingDocument.Open(filepathFrom, True)
Console.WriteLine("Doc Source open")
Dim sourceHeader = wdDocSource.MainDocumentPart.HeaderParts.FirstOrDefault()
If sourceHeader IsNot Nothing Then
For Each part In sourceHeader.GetPartsOfType(Of ImagePart)()
Dim id = sourceHeader.GetIdOfPart(part)
Dim imgpart = TargetheaderPart.AddNewPart(Of ImagePart)("image/jpeg", id)
imgpart.FeedData(part.GetStream)
Next
TargetheaderPart.FeedData(sourceHeader.GetStream())
Console.WriteLine("header replaced")
End If
wdDocSource.Close()
End Using

Julien
When creating document from scratch there are no SectionProperties
Hi 
If you are creating the whole document from scratch, there are no SectionProperties defined you will have to append the reference yourself:
<code>
'VB.net
Sub CreateWordDoc (ByRef TargetPath as String)
dim wordDoc as  WordprocessingDocument = WordprocessingDocument.Create(TargetPath, WordprocessingDocumentType.Document)
Dim mainPart As MainDocumentPart = wordDoc.AddMainDocumentPart
dim body as Body
Dim HeaderPart As HeaderPart
Dim headerRef As HeaderReference = New HeaderReference()
Dim rHeaderID as String

mainPart.Document = New Document
body = mainPart.Document.AppendChild(New Body())
' Delete any existing header part.
mainPart.DeleteParts(mainPart.HeaderParts)
'adding header
HeaderPart = mainPart.AddNewPart(Of HeaderPart)()
rHeaderID = mainPart.GetIdOfPart(HeaderPart)
headerRef.Id = rHeaderID
'write your header
'.......
If mainPart.Document.Body.Elements(Of SectionProperties).Count = 0 Then
     'No references need to add one to the header 
     body.Append(New SectionProperties(headerRef))
Else
     Dim sectPrs = mainPart.Document.Body.Elements(Of SectionProperties)()
     For Each sectPr In sectPrs
           sectPr.RemoveAllChildren(Of HeaderReference)()
           sectPr.PrependChild(headerRef)
     Next
End If
End Sub
</code>
Mistake in the Sample
There is a problem in the sample provided. Once you add the HeaderReference, you need to provide the releationship id as well. Basically
this line

sectPr.PrependChild(Of HeaderReference)(New HeaderReference())

should be replaced with 

 sectPr.PrependChild(Of HeaderReference)(New HeaderReference() With {.Type = HeaderFooterValues.Default, .Id = rId })

Thanks,
Ankush
Problem with image
It doesn't work with images in the header
No SectionProperties
I am trying to use this code, trying to generate Header on a XML Document File, but the it comes to the next line

foreach (var sectPr in sectPrs)

I have not items on the sectPrs Collection so it cannot create the new header reference node.