问题
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.
回答1:
I'm quite sure what is wrong with your code, I suspect its the way you are changing the references.
In any case I have a working example which you should hopefully guide you.
I've based mine from examples here: http://msdn.microsoft.com/en-us/library/office/cc546917.aspx
I used the Open XML SDK 2.0 Productivity Tool to Generate the Header and Footer parts. I first create a document with my desired layout then open it with the tool, it generates the XML or Code. You can get it here: http://www.microsoft.com/en-us/download/details.aspx?id=5124
The only caveat to this is that it assumes the document already some content in the body, a single letter will do. I'm not sure if this can be avoided, I tried opening an empty document in the Productivity Tool and it suffers from the same error - "Cannot open the file: Archive file cannot be size 0". In my sample it will fail on WordprocessingDocument.Open
.
Maybe in the case of an empty document you have to create a body first. In any case I suspect the main aim of this question is to add a header and footer so I feel this is a valid answer.
If you want I can provide the actual cs/project files.
Hope this helps.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
namespace HeaderFooterDocX
{
class Program
{
static void Main(string[] args)
{
ChangeHeader(@"C:\Users\James\Desktop\Document.docx");
}
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 });
}
}
}
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;
}
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;
}
}
}
回答2:
this code worked for me. Take into consideration:
- header's relationship Id is "r97" in my example. Perhaps you would like to decide a unique rId on your own
- same for footer's relationshipId ("r98")
- Both header and footer have a hardcoded paragraph with some text.
I am assuming a document already exists
using (WordprocessingDocument doc = WordprocessingDocument.Open(destination, true)) { var mainDocPart = doc.MainDocumentPart; if (doc == null) { mainDocPart = doc.AddMainDocumentPart(); } if (mainDocPart.Document == null) { mainDocPart.Document = new Document(); } ApplyHeader(doc); ApplyFooter(doc); }
ApplyHeader method:
public static void ApplyHeader(WordprocessingDocument doc)
{
// Get the main document part.
MainDocumentPart mainDocPart = doc.MainDocumentPart;
HeaderPart headerPart1 = mainDocPart.AddNewPart<HeaderPart>("r97");
Header header1 = new Header();
Paragraph paragraph1 = new Paragraph(){ };
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "Header stuff";
run1.Append(text1);
paragraph1.Append(run1);
header1.Append(paragraph1);
headerPart1.Header = header1;
SectionProperties sectionProperties1 = mainDocPart.Document.Body.Descendants<SectionProperties>().FirstOrDefault();
if (sectionProperties1 == null)
{
sectionProperties1 = new SectionProperties() { };
mainDocPart.Document.Body.Append(sectionProperties1);
}
HeaderReference headerReference1 = new HeaderReference() { Type = HeaderFooterValues.Default, Id = "r97" };
sectionProperties1.InsertAt(headerReference1,0);
}
ApplyFooter method:
public static void ApplyFooter(WordprocessingDocument doc)
{
// Get the main document part.
MainDocumentPart mainDocPart = doc.MainDocumentPart;
FooterPart footerPart1 = mainDocPart.AddNewPart<FooterPart>("r98");
Footer footer1 = new Footer();
Paragraph paragraph1 = new Paragraph() { };
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "Footer stuff";
run1.Append(text1);
paragraph1.Append(run1);
footer1.Append(paragraph1);
footerPart1.Footer = footer1;
SectionProperties sectionProperties1 = mainDocPart.Document.Body.Descendants<SectionProperties>().FirstOrDefault();
if (sectionProperties1 == null)
{
sectionProperties1 = new SectionProperties() { };
mainDocPart.Document.Body.Append(sectionProperties1);
}
FooterReference footerReference1 = new FooterReference() { Type = DocumentFormat.OpenXml.Wordprocessing.HeaderFooterValues.Default, Id = "r98" };
sectionProperties1.InsertAt(footerReference1, 0);
}
Enjoy,
回答3:
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;
}
来源:https://stackoverflow.com/questions/11672991/add-header-and-footer-to-an-existing-empty-word-document-with-openxml-sdk-2-0