<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d8211560\x26blogName\x3dTech+Tips,+Tricks+%26+Trivia\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLUE\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttp://mvark.blogspot.com/search\x26blogLocale\x3den\x26v\x3d2\x26homepageUrl\x3dhttp://mvark.blogspot.com/\x26vt\x3d-5147029996388199615', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>

Tech Tips, Tricks & Trivia

by 'Anil' Radhakrishna
An architect's notes, experiments, discoveries and annotated bookmarks.

Search from over a hundred HOW TO articles, Tips and Tricks


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

Labels: , , ,

Tweet this | Google+ it | Share on FB

« Home | Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »

Posted by Blogger Jair Almeida Peña | 9/30/2010 11:04:00 PM

Interesting topic. I have a problem inserting images as these are not shown. Can you help me please.    



Posted by Blogger Jair Almeida Peña | 9/30/2010 11:05:00 PM

Interesting topic. I have a problem inserting images as these are not shown. Can you help me please.    



Posted by Anonymous Anonymous | 5/05/2011 01:22:00 PM

I applied this code but when we set the margins of the table it stops showing header and footer on the page..Please suggest    



Posted by Anonymous Anonymous | 5/11/2011 03:24:00 PM

Hi!

The thing that you should do so that the header and the footer will not appear on the body is that create again another table. for the body..



I do have a question, how can i insert a logo in the header? thanks!    



Posted by Anonymous Anonymous | 5/17/2011 01:35:00 PM

Its really helpful for me.


Avneesh Pandey,
Software Engg.
Xcino Inc    



Posted by Anonymous Anonymous | 9/20/2011 10:35:00 AM

Thank you very much Anil
you save my day :)
Nanthini    



Posted by Blogger Chris Dove | 12/22/2011 06:46:00 PM

Great post! excellent point of refrence though my header and footers are doubling up e.g. one shown in the header and one in the content    



Posted by Anonymous Anonymous | 9/12/2012 10:13:00 AM

Tried the same concept in ColdFusion. Just wrapped my header and footer in a div and gave it the style with the 9in left margin. It works, as the header and footer don't appear in the body of my document, however it adds 2 extra blank pages. Any way to prevent that??    



Posted by Blogger Aditya bhatnagar | 8/21/2013 12:42:00 PM

How to set background image in word file using c# code??    



Posted by OpenID RHPT | 4/08/2014 03:45:00 AM

Is there a way to do this with your method but skip the first page, meaning have the numbering start on the second page?    



Posted by Blogger Anil | 4/08/2014 06:47:00 PM

Any setting that is possible in MS Word can also be accomplished by code. Starting page numbering on page 2 can be done - http://office.microsoft.com/en-001/word-help/start-page-numbering-on-page-2-HP001227657.aspx Create a sample Word document with that setting and then save that document as a Webpage. A HTML page is created along with dependent files in a folder with the same name as the web page. Identify the HTML, CSS code that is causing the page number to show up and modify the above code. This will require some experimenting. Due to time constraints, I cannot do it myself but let me know if you run into any issues and I'll jump in then.    



Posted by OpenID RHPT | 4/09/2014 07:48:00 AM

Thank you! That tricked worked.    



Posted by Blogger Arun Shankar | 7/16/2015 06:00:00 PM

When my document got exported it came up with additional square character symbol as shown below. Can anyone help with this?    



Posted by Blogger Bhatia Dhara | 4/11/2017 10:16:00 AM

Heyyy..thats help me alot..but having a problem in image..how to set image height width because it shows original image height width..and width height style doesn't effect on it..any suggestion please
   



»

Post a Comment