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.
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:
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 }); } } }
Reference
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.
- 12/15/2010
- jregist
- 4/2/2012
- Thomas Lee
[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.
- 5/4/2011
- mrdall
- 4/2/2012
- Thomas Lee
[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.
- 5/4/2011
- mrdall
- 4/2/2012
- Thomas Lee
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.
- 5/17/2011
- mrdall
- 4/2/2012
- Thomas Lee
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
- 12/20/2011
- Jul_Buel
- 4/2/2012
- Thomas Lee
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>
- 8/17/2010
- gwaddell
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
- 7/19/2010
- Ankush Bhatia
- 4/19/2010
- Fernando Hunth
- 4/20/2010
- Thomas Lee
foreach (var sectPr in sectPrs)
I have not items on the sectPrs Collection so it cannot create the new header reference node.
- 4/1/2010
- Fernando Hunth