Using iTextSharp to generate PDF with Header and Footer
by
on June 26th, 2010 at 07:03 AM (24926 Views)
This one had me struggling for a while, so I thought I'd post a blog about it to try and help others.
What I was trying to do was create a PDF including header and footer sections to print documents onto a headed paper style.
Using iTextSharp V5.0.2.0 DLL in the bin folder you can create PDFs on the fly. My previous blog explained how to generate a simple PDF. Next I wanted to generate something a bit more complicated.
It seems previous versions of iTextSharp used a different method for producing headers and footers, but the more recent releases use an event handler to allow you to manipulate the document during various stages of it's production.
The first thing to do is create a class that will provide the event handler methods. This inherits the PdfPageEventHelper class from iTextSharp, like so:-
Then, on your PDF page, you need to add your event handler to the PDF instance. This can be done like this-Code:using System; using System.Web; using iTextSharp.text; using iTextSharp.text.pdf; namespace myApp.ns.pages { public class pdfPage : iTextSharp.text.pdf.PdfPageEventHelper { //I create a font object to use within my footer protected Font footer { get { // create a basecolor to use for the footer font, if needed. BaseColor grey = new BaseColor(128, 128, 128); Font font = FontFactory.GetFont("Arial", 9, Font.Normal, grey); return font; } } //override the OnStartPage event handler to add our header public override void OnStartPage(PdfWriter writer, Document doc) { //I use a PdfPtable with 1 column to position my header where I want it PdfPTable headerTbl = new PdfPTable(1); //set the width of the table to be the same as the document headerTbl.TotalWidth = doc.PageSize.Width; //I use an image logo in the header so I need to get an instance of the image to be able to insert it. I believe this is something you couldn't do with older versions of iTextSharp Image logo = Image.GetInstance(HttpContext.Current.Server.MapPath("/images/logo.jpg")); //I used a large version of the logo to maintain the quality when the size was reduced. I guess you could reduce the size manually and use a smaller version, but I used iTextSharp to reduce the scale. As you can see, I reduced it down to 7% of original size. logo.ScalePercent(7); //create instance of a table cell to contain the logo PdfPCell cell = new PdfPCell(logo); //align the logo to the right of the cell cell.HorizontalAlignment = Element.ALIGN_RIGHT; //add a bit of padding to bring it away from the right edge cell.PaddingRight = 20; //remove the border cell.border = 0; //Add the cell to the table headerTbl.AddCell(cell); //write the rows out to the PDF output stream. I use the height of the document to position the table. Positioning seems quite strange in iTextSharp and caused me the biggest headache.. It almost seems like it starts from the bottom of the page and works up to the top, so you may ned to play around with this. headerTbl.WriteSelectedRows(0,-1, 0, (doc.PageSize.Height-10), writer.DirectContent); } //override the OnPageEnd event handler to add our footer public override void OnEndPage(PdfWriter writer, Document doc) { //I use a PdfPtable with 2 columns to position my footer where I want it PdfPTable footerTbl = new PdfPTable(2); //set the width of the table to be the same as the document footerTbl.TotalWidth = doc.PageSize.Width; //Center the table on the page footerTbl.HorizontalAlignment = Element.ALIGN_CENTER; //Create a paragraph that contains the footer text Paragraph para = new Paragraph("Some footer text", footer); //add a carriage return para.Add(Environment.NewLine); para.Add("Some more footer text"); //create a cell instance to hold the text PdfPCell cell = new PdfPCell(para); //set cell border to 0 cell.Border = 0; //add some padding to bring away from the edge cell.PaddingLeft = 10; //add cell to table footerTbl.AddCell(cell); //create new instance of Paragraph for 2nd cell text para = new Paragraph("Some text for the second cell", footer); //create new instance of cell to hold the text cell = new PdfPCell(para); //align the text to the right of the cell cell.HorizontalAlignment = Element.ALIGN_RIGHT; //set border to 0 cell.Border = 0; // add some padding to take away from the edge of the page cell.PaddingRight = 10; //add the cell to the table footerTbl.AddCell(cell); //write the rows out to the PDF output stream. footerTbl.WriteSelectedRows(0,-1, 0, (doc.BottomMargin + 10), writer.DirectContent); } } }
That should be it! You will have your header and footer in the correct place on every page.Code:using System; using System.Web; using System.IO; using iTextSharp.text; using iTextSharp.text.pdf; using myApp.ns.pages; protected void Page_Load(object sender, EventArgs e) { //create an instance of a PDF document. You may need to play with the margins to ensure the "look" is right Document doc = new Document(PageSize.A4, 42, 53, 70, 46); //Change the content type to PDF HttpContext.Current.Response.ContentType = "application/pdf"; //create an instance of your PDFpage class. This is the class we generated above. pdfPage page = new pdfPage(); //create an instance of the PdfWriter and write to the Response.OutputStream. This will stream it directly to the browser PdfWriter pdfWriter = PdfWriter.GetInstance(doc, HttpContext.Current.Response.OutputStream); //set the PageEvent of the pdfWriter instance to the instance of our PDFPage class pdfWriter.PageEvent = page; //open the document doc.Open(); //this is just some default text I used. a Paragraph instance is just repeated 100 times Paragraph para; for (int x = 1; x <= 100; x++) { para = new Paragraph("This is a paragraph"); doc.Add(para); } //close the document doc.Close(); }
The things you'll have to play around with are the page margins to ensure they don't overlap the header or footer areas. Using the event handlers, our header and footer tables use absolute positioning to put them in the right place, so you may need to make some adjustments where necessary.
Hope that helps someone.









Email Blog Entry