HOW TO add a header or footer to a dynamically generated Word document
There was a question recently on my CodeProject article "Dynamically generate a MS Word document using HTML & CSS". The article describes how to generate a Word document programmatically without using any components, by exploiting the formatting features exposed through Office XML and CSS. The questioner wanted to know how to add a custom header and footer and show something like Page X of Y (total pages).
Based on what I have tried so far, showing a header and footer using Office XML in MS Word is not as easy as it is in Excel. If you want to keep the code simple & don't need any great fireworks i.e. you will just settle for page numbers in the header or footer then it's a matter of adding a few lines to the original source code. The code can be viewed at this Github Gist
Update (1-Sep-2010): To add a custom header & footer, check this new post
To add a footer that shows Page number at the bottom right, here are the steps -
1) Add these classes inside the style tags-
p.MsoFooter, li.MsoFooter, div.MsoFooter
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
tab-stops:center 3.0in right 6.0in;
font-size:12.0pt;}
Tweak the MsoFooter class that is referenced by the footer, as required.
2) Add following line to @page Section1 definition -
mso-footer: f1;
3) Add this div block before the end body tag -
<div style='mso-element:footer' id=f1>
<p class=MsoFooter>
<span style='mso-tab-count:2'></span><span style='mso-field-code:" PAGE "'></span>
</p>
</div>
Setting the value of mso-tab-count attribute to 2 moves it to the rightmost edge. Set mso-tab-count attribute to 1 to center it and drop the span tag & style attribute altogether if you want Page number in the footer on the left.
The process to add a Header that shows Page number at the center is similar to the steps described above.
1) Add these classes inside the style tags-
p.MsoHeader, li.MsoHeader, div.MsoHeader
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
tab-stops:center 3.0in right 6.0in;
font-size:12.0pt;
font-family:"Times New Roman";}
Tweak the MsoHeader class that is referenced by the footer, as required.
2) Add following line to @page Section1 definition -
mso-header: h1;
3) Add this div block before the end body tag -
<div style='mso-element:header' id=h1>
<p class=MsoHeader><span style='mso-tab-count:1'></span>
<span style='mso-field-code:" PAGE "'></span>
</p>
</div>
Make sure that you also programatically set the document to open in "Print Layout" mode. The Header & Footer will not be visible in the default "Web Layout" view.
To arrive at this solution we have basically replicated the same technique that Word uses to store header and footer data with key inputs from the Office HTML and XML Reference.
"Word does not display header and footer information in an HTML page, but it does store the data.
Header and footer information is stored in a separate file named Header.htm. Inside the file, the header and footer information is stored as fields, using Span elements with the mso-element:field-begin, mso-element:field-separator, and mso-element:field-end attributes in conjunction with the MsoHeader and MsoPageNumber styles."
The attempt here is to encapsulate the settings of external Header.htm link file directly into our main page. As we have to keep things simple, all the available Word Header & Footer tokens are not accomodated.
By encapsulating the features of external Header.htm file directly into our main page to keep the solution simple, we loose the ability to use all the available Word Header & Footer tokens.
Related links:
HOW TO implement "Download as Word/Excel" functionality through a web page
HOW TO send an email with a Word or Excel file attachment built on the fly
HOW TO generate a Word document dynamically with user submitted text formatted with Free Text Box
Based on what I have tried so far, showing a header and footer using Office XML in MS Word is not as easy as it is in Excel. If you want to keep the code simple & don't need any great fireworks i.e. you will just settle for page numbers in the header or footer then it's a matter of adding a few lines to the original source code. The code can be viewed at this Github Gist
Update (1-Sep-2010): To add a custom header & footer, check this new post
To add a footer that shows Page number at the bottom right, here are the steps -
1) Add these classes inside the style tags-
p.MsoFooter, li.MsoFooter, div.MsoFooter
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
tab-stops:center 3.0in right 6.0in;
font-size:12.0pt;}
Tweak the MsoFooter class that is referenced by the footer, as required.
2) Add following line to @page Section1 definition -
mso-footer: f1;
3) Add this div block before the end body tag -
<div style='mso-element:footer' id=f1>
<p class=MsoFooter>
<span style='mso-tab-count:2'></span><span style='mso-field-code:" PAGE "'></span>
</p>
</div>
Setting the value of mso-tab-count attribute to 2 moves it to the rightmost edge. Set mso-tab-count attribute to 1 to center it and drop the span tag & style attribute altogether if you want Page number in the footer on the left.
The process to add a Header that shows Page number at the center is similar to the steps described above.
1) Add these classes inside the style tags-
p.MsoHeader, li.MsoHeader, div.MsoHeader
{margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
tab-stops:center 3.0in right 6.0in;
font-size:12.0pt;
font-family:"Times New Roman";}
Tweak the MsoHeader class that is referenced by the footer, as required.
2) Add following line to @page Section1 definition -
mso-header: h1;
3) Add this div block before the end body tag -
<div style='mso-element:header' id=h1>
<p class=MsoHeader><span style='mso-tab-count:1'></span>
<span style='mso-field-code:" PAGE "'></span>
</p>
</div>
Make sure that you also programatically set the document to open in "Print Layout" mode. The Header & Footer will not be visible in the default "Web Layout" view.
To arrive at this solution we have basically replicated the same technique that Word uses to store header and footer data with key inputs from the Office HTML and XML Reference.
"Word does not display header and footer information in an HTML page, but it does store the data.
Header and footer information is stored in a separate file named Header.htm. Inside the file, the header and footer information is stored as fields, using Span elements with the mso-element:field-begin, mso-element:field-separator, and mso-element:field-end attributes in conjunction with the MsoHeader and MsoPageNumber styles."
The attempt here is to encapsulate the settings of external Header.htm link file directly into our main page. As we have to keep things simple, all the available Word Header & Footer tokens are not accomodated.
By encapsulating the features of external Header.htm file directly into our main page to keep the solution simple, we loose the ability to use all the available Word Header & Footer tokens.
Related links:
HOW TO implement "Download as Word/Excel" functionality through a web page
HOW TO send an email with a Word or Excel file attachment built on the fly
HOW TO generate a Word document dynamically with user submitted text formatted with Free Text Box
The method described successfully puts a footer in the document, but it also puts the footer text in the BODY of the document. Do you know any way to avoid this? If not, you allude to a more complicated way to write headers and footers (i.e. "great fireworks"). Can you provide any resources for that method?
ReplyDeleteYou will notice if you save a Word document as a web page that it creates a file named Header.htm (in a supporting folder). This is the file in which Word stores header and footer data. The solution to show header &/or footer properly without showing it in the document, lies in replicating the behavior of Header.htm which involves complex CSS.
ReplyDeleteIf you want to be cheap and save yourself a little time, just write a function to remove the straggling header/footer content from the end of the word document - delete all ranges after a particular marker you have put in.
ReplyDeleteis there a simple mso-field-code similar to page to place a couple of words instead of page number there?
ReplyDeleteI need to put some text instead of page numbers in there and this method seems the most direct if I can find.
Thanks,
I was wondering, could you share with me the complex css required to not have the footer repeat in the body? I currently am working on a project that requires perfection.
ReplyDeleteTHANK YOU VERY MUCH!
aSandman
asandman@njcure.com
Has anyone figured out the css or a way to not have the text show up in the body at the end of the documnet?
ReplyDeleteThanks!
That was a nice code ,But I am getting header and footer in the document also can anyone help to get that complex css it will be very much helpful in my project. Thanks in advance..
ReplyDeleteHas anyone figured out the css or a way to not have the text show up in the body at the end of the documnet?
ReplyDeleteIncluding header and footer in this method is wonderful, but stuck with the same problem. Header and footer are appearing in the body of the document. Could someone kindly share the solution to handle this. Thanks !
ReplyDeleteHi,
ReplyDeleteThe code to include header footer is really useful, but it appears in the body of the document also.
Could you please share the solution for the problem.
The same problem, header and footer is appearing in the document body, please help to solve.
ReplyDeleteI have the same header and footer problem, appearing on the body.
ReplyDeleteAnd I'd like to know how to embed an image into word document.
Thanks!
Has anyone found a solution to the problem that everyone is having? The footer appearing twice on the page...
ReplyDeleteC'mon guys lets put our heads together and brainstorm!!
I've tried putting the fields inside invisible spans but that doesn't change their visibility.
I've tried looking for documentation on 'mso-field-code' to see if there is a pure text one, but I can't find anything on this, only forums full of people asking the same question.
I urge the author of this documentation to try and help us find a solution, or at least a work around.
Put the footer in a separate file (just put the html/head/body-tags around the original footer and save it as footer.htm).
ReplyDeleteThen change the style declaration to
@page Section1{mso-footer:url('http://..path../footer.htm') f1}.
Word is complaining about files not being in expected places, but it works.
Adding an image to the footer requires in the head-section and in the footer-body.
I see the last line in my previous comment is missing the code which should appear in the footer-file.
ReplyDeleteIn the header goes:
<xml:namespace ns='urn:schemas-microsoft-com:vml' prefix='v'/>
In the body goes:
<v:imagedata src='http://www.emailenquete.nl/logo200print.jpg'/>
Hi, I am trying to create bullets from the HTML code to appear in my generated Word document. So far I have tried
ReplyDelete<--span style='font-size:9.0pt;font-family:Symbol'>· <--/span>
but that displays a strange R letter in front of the bullet. Can someone tell me the appropriate HTML tag to create a bullet when exporting to Word? Thanks.
Use the following codes (without the quotes) instead of the actual bullet -
ReplyDelete"•" - Bullet
"‣" - Triangular Bullet
Use the following entity numbers instead of the actual bullet -
ReplyDelete& #149; - Bullet
Note - Remove the space between & and #. I had to put that space as an actual bullet was getting rendered when I posted the response
For more info on character codes, refer to this link - http://www.erns-eporium.co.uk/ansi.htm
Did any one find solution to this prbm????
ReplyDeleteTo add a custom header & footer, try the hack described in this new post - http://mvark.blogspot.com/2010/09/how-to-dynamically-generate-word.html
ReplyDeleteI've tested the hack with Word 2007. You will have to test that it works fine in older versions of MS Word if your target audience uses those.