1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Need help? Ask us a question. Ask Question

Using iTextSharp to generate PDF with Header and Footer

Blog entry posted by richyrich, Jun 26, 2010.

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 using ASP.NET C# to include 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 in .NET C# that will provide the event handler methods. This inherits the PdfPageEventHelper class from iTextSharp, like so:-
Code (text):

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);
}
}
}
 
Then, on your PDF page, you need to add your event handler to the PDF instance. This can be done like this-
Code (text):

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();
}
 
That should be it! You will have your header and footer in the correct place on every page.

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.
  1. richyrich
    The second piece of code is the Page_Load event of a .aspx page. I guess it should have been within a partial page class. But if you were to generate a new .aspx page, the second piece of code would be the Page_Load event.

    Hope that helps explain it
  2. Ishan
    How to run this code.? and where is Main class?
    I made class1.cs and copied 1st code, and made class2.cs and copied 2nd code.
    Now? what is next?
  3. richyrich
    Hi
    Adding headers and footers to pages shouldn't affect the document itself. Have you tried generating the PDF without setting the PageEvent of the PdfWriter instance?

    So, basically, comment out this line:-
    pdfWriter.PageEvent = page;

    Does it still add the additional blank pages?
  4. Bhushan
    this code worked but it adds a blank page only with headers in the starting and at the end of the file.
    can you tell me how to avoid these blank page.
  5. Dipali Wagh
    thank, this code worked
    jmurrayhead likes this.