HOW TO dynamically generate a Word document with custom header & footer

Way back in 2004, a project I was working on required a web page to be exported as a Word document (.DOC). Without relying on any components, I utilized the Office XML & HTML technique to implement this feature. I posted my sample on CodeProject to seek feedback. Over the years, I've received some generous comments & feature requests. Many wanted to know how to add a header & footer to the dynamically generated Word document.

With the help of the Microsoft Office HTML and XML Reference, I devised a hack to add a lacklustre header and/or footer. Some folks wanted to customize the contents of the header & footer but when they tried with my hack that offered limited functionality, the header/footer text showed up in the document body to their annoyance. This July, an ingenious developer posted a hack that can overcome this problem, in the Comments section of my CodeProject article. His practical workaround was to pack the duplicating header/footer text inside a table & push it off the page's dimensions with CSS.



For those interested, I adapted his VB.NET snippet into a complete sample in C#. Instead of using a ASP.NET webform as I did in the original code sample in the article, I have used a Generic Handler (.ASHX) to dynamically generate a Word document as it is more suitable for this purpose.

<%@ WebHandler Language="C#" Class="Handler" %>


using System;
using System.Web;
using System.Text;

public class Handler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringBuilder sbTop = new System.Text.StringBuilder();
sbTop.Append(@"
<html
xmlns:o='urn:schemas-microsoft-com:office:office'
xmlns:w='urn:schemas-microsoft-com:office:word'
xmlns='http://www.w3.org/TR/REC-html40'>
<head><title></title>

<!--[if gte mso 9]>
<xml>
<w:WordDocument>
<w:View>Print</w:View>
<w:Zoom>90</w:Zoom>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml>
<![endif]-->


<style>
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;
}
<style>

<!-- /* Style Definitions */

@page Section1
{
size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in ;
mso-header-margin:.5in;
mso-header:h1;
mso-footer: f1;
mso-footer-margin:.5in;
}


div.Section1
{
page:Section1;
}

table#hrdftrtbl
{
margin:0in 0in 0in 9in;
}
-->
</style></head>

<body lang=EN-US style='tab-interval:.5in'>
<div class=Section1>
<h1>Time and tide wait for none</h1>
The quick brown fox jumps over the lazy dog
...
...


<table id='hrdftrtbl' border='1' cellspacing='0' cellpadding='0'>
<tr><td>
<div style='mso-element:header' id=h1 >
<p class=MsoHeader style='text-align:center'>Confidential</p>
</div>
</td>
<td>
<div style='mso-element:footer' id=f1>
<p class=MsoFooter>Draft
<span style=mso-tab-count:2'></span><span style='mso-field-code:"" PAGE ""'></span>
of <span style='mso-field-code:"" NUMPAGES ""'></span></p></div>
/td></tr>
</table>
</body></html>
");

string strBody = sbTop.ToString();
context.Response.AppendHeader("Content-Type", "application/msword");
context.Response.AppendHeader("Content-disposition", "attachment; filename=HeaderFooter.doc");
context.Response.Write(strBody);
}


public bool IsReusable
{
get
{
return false;
}
}
}

To clearly understand the code you would have to download the Microsoft Office HTML and XML Reference which is in .CHM format (as there is no online version of it) & look up the exact meanings of custom CSS properties.

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