Add Header and Footer to an existing empty word document with OpenXML SDK 2.0

c#, footer, header, ms-word, openxml-sdk

Solution

I find the solution by myself.

In fact, adding a header or a footer in a docx with OpenXml involves that :

Document has to exist.

Saving and closing document before adding a header or a footer does not work.

WordprocessingDocument document = WordprocessingDocument.Open(path, true);
<operations on docx>
document.Save();
document.Close();
ChangeHeader(document);

You have to re-open a second time your docx to create a new instanciation of the document.

Correct solution will be (with James Wood solution):

WordprocessingDocument document = WordprocessingDocument.Open(path, true);
<operations on docx>
document.Save();
document.Close();
ChangeHeader(path);

    public static void ChangeHeader(String documentPath)
    {
        // Replace header in target document with header of source document.
        using (WordprocessingDocument document = WordprocessingDocument.Open(documentPath, true))
        {
            // Get the main document part
            MainDocumentPart mainDocumentPart = document.MainDocumentPart;

            // Delete the existing header and footer parts
            mainDocumentPart.DeleteParts(mainDocumentPart.HeaderParts);
            mainDocumentPart.DeleteParts(mainDocumentPart.FooterParts);

            // Create a new header and footer part
            HeaderPart headerPart = mainDocumentPart.AddNewPart<HeaderPart>();
            FooterPart footerPart = mainDocumentPart.AddNewPart<FooterPart>();

            // Get Id of the headerPart and footer parts
            string headerPartId = mainDocumentPart.GetIdOfPart(headerPart);
            string footerPartId = mainDocumentPart.GetIdOfPart(footerPart);

            GenerateHeaderPartContent(headerPart);

            GenerateFooterPartContent(footerPart);

            // Get SectionProperties and Replace HeaderReference and FooterRefernce with new Id
            IEnumerable<SectionProperties> sections = mainDocumentPart.Document.Body.Elements<SectionProperties>();

            foreach (var section in sections)
            {
                // Delete existing references to headers and footers
                section.RemoveAllChildren<HeaderReference>();
                section.RemoveAllChildren<FooterReference>();

                // Create the new header and footer reference node
                section.PrependChild<HeaderReference>(new HeaderReference() { Id = headerPartId });
                section.PrependChild<FooterReference>(new FooterReference() { Id = footerPartId });
            }
        }
    }


public static void GenerateHeaderPartContent(HeaderPart part)
        {
            Header header1 = new Header() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "w14 wp14" } };
            header1.AddNamespaceDeclaration("wpc", "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas");
            header1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
            header1.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
            header1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
            header1.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
            header1.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
            header1.AddNamespaceDeclaration("wp14", "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
            header1.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
            header1.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
            header1.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
            header1.AddNamespaceDeclaration("w14", "http://schemas.microsoft.com/office/word/2010/wordml");
            header1.AddNamespaceDeclaration("wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup");
            header1.AddNamespaceDeclaration("wpi", "http://schemas.microsoft.com/office/word/2010/wordprocessingInk");
            header1.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
            header1.AddNamespaceDeclaration("wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape");

            Paragraph paragraph1 = new Paragraph() { RsidParagraphAddition = "00164C17", RsidRunAdditionDefault = "00164C17" };

            ParagraphProperties paragraphProperties1 = new ParagraphProperties();
            ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId() { Val = "Header" };

            paragraphProperties1.Append(paragraphStyleId1);

            Run run1 = new Run();
            Text text1 = new Text();
            text1.Text = "Header";

            run1.Append(text1);

            paragraph1.Append(paragraphProperties1);
            paragraph1.Append(run1);

            header1.Append(paragraph1);

            part.Header = header1;
        }

        public static void GenerateFooterPartContent(FooterPart part)
        {
            Footer footer1 = new Footer() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "w14 wp14" } };
            footer1.AddNamespaceDeclaration("wpc", "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas");
            footer1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
            footer1.AddNamespaceDeclaration("o", "urn:schemas-microsoft-com:office:office");
            footer1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
            footer1.AddNamespaceDeclaration("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
            footer1.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml");
            footer1.AddNamespaceDeclaration("wp14", "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing");
            footer1.AddNamespaceDeclaration("wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing");
            footer1.AddNamespaceDeclaration("w10", "urn:schemas-microsoft-com:office:word");
            footer1.AddNamespaceDeclaration("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
            footer1.AddNamespaceDeclaration("w14", "http://schemas.microsoft.com/office/word/2010/wordml");
            footer1.AddNamespaceDeclaration("wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup");
            footer1.AddNamespaceDeclaration("wpi", "http://schemas.microsoft.com/office/word/2010/wordprocessingInk");
            footer1.AddNamespaceDeclaration("wne", "http://schemas.microsoft.com/office/word/2006/wordml");
            footer1.AddNamespaceDeclaration("wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape");

            Paragraph paragraph1 = new Paragraph() { RsidParagraphAddition = "00164C17", RsidRunAdditionDefault = "00164C17" };

            ParagraphProperties paragraphProperties1 = new ParagraphProperties();
            ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId() { Val = "Footer" };

            paragraphProperties1.Append(paragraphStyleId1);

            Run run1 = new Run();
            Text text1 = new Text();
            text1.Text = "Footer";

            run1.Append(text1);

            paragraph1.Append(paragraphProperties1);
            paragraph1.Append(run1);

            footer1.Append(paragraph1);

            part.Footer = footer1;
        }

Problem

I'm trying to add a Header and Footer to an empty word document. I use this code to add Header part in word/document.xml when change docx to zip. ``` ApplyHeader(doc); public static void ApplyHeader(WordprocessingDocument doc) { // Get the main document part. MainDocumentPart mainDocPart = doc.MainDocumentPart; // Delete the existing header parts. mainDocPart.DeleteParts(mainDocPart.HeaderParts); // Create a new header part and get its relationship id. HeaderPart newHeaderPart = mainDocPart.AddNewPart<HeaderPart>(); string rId = mainDocPart.GetIdOfPart(newHeaderPart); // Call the GeneratePageHeaderPart helper method, passing in // the header text, to create the header markup and then save // that markup to the header part. GeneratePageHeaderPart("Test1").Save(newHeaderPart); // Loop through all section properties in the document // which is where header references are defined. foreach (SectionProperties sectProperties in mainDocPart.Document.Descendants<SectionProperties>()) { // Delete any existing references to headers. foreach (HeaderReference headerReference in sectProperties.Descendants<HeaderReference>()) sectProperties.RemoveChild(headerReference); // Create a new header reference that points to the new // header part and add it to the section properties. HeaderReference newHeaderReference = new HeaderReference() { Id = rId, Type = HeaderFooterValues.First }; sectProperties.Append(newHeaderReference); } // Save the changes to the main document part. mainDocPart.Document.Save(); } private static Header GeneratePageHeaderPart(string HeaderText) { var element = new Header( new Paragraph( new ParagraphProperties( new ParagraphStyleId() { Val = "Header1" }), new Run( new Text(HeaderText)) ) ); return element; } ``` This code works but there's no header relationship created in word/_rels/document.xml.rels. ``` <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/> <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/> <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/> <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/> <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/> </Relationships> ``` And no more content type header in [Content_Types].xml ``` <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/> <Default Extension="xml" ContentType="application/xml"/> <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/> <Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/> <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/> <Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/> <Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/> <Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/> <Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/> <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/> </Types> ``` Nevertheless, header.xml was created in word/ ``` <?xml version="1.0" encoding="utf-8"?><w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:p><w:pPr><w:pStyle w:val="Header1" /></w:pPr><w:r><w:t>Test1</w:t></w:r></w:p></w:hdr> ``` And my word/document.xml to show that my header is added. ``` <w:sectPr w:rsidR="003310CE" w:rsidSect="00D928B6"> <w:pgSz w:w="11906" w:h="16838" /> <w:pgMar w:top="1417" w:right="1417" w:bottom="1417" w:left="1417" w:header="708" w:footer="708" w:gutter="0" /> <w:cols w:space="708" /><w:docGrid w:linePitch="360" /> <w:headerReference w:type="first" r:id="Recfa318e6a7c44ff" /> </w:sectPr> ``` So my question is how to add header and footer correctly ? Thanks for your help.

Original source