Massoud Mazar

Sharing The Knowledge

NAVIGATION - SEARCH

Code sample for using iTextSharp PDF library

iTextSharp is a rich code library to create PDF and RTF output. Recently I decided to use it for a client and realized there are not much good code examples available on the internet. Even some of the code samples from its online tutorial wont run.

By doing a lot of try and error and with some help from other posts, I could get the desired output. It took me too much time to gather all this information and thought it may come handy to others. So I put together a sample web application which creates a PDF document and renders it to the client browser. Here is the code behind for the page:

public partial class _Default : System.Web.UI.Page
     {
         protected void Page_Load(object sender, EventArgs e)
         {
             SendOutPDF(new CustomReports().CreatePDF("Title: Sample 1"));
         }
        /// 
         /// Sends a Stream of bytes to Client as a PDF file
         /// 
         /// Stream containing bytes
         protected void SendOutPDF(System.IO.MemoryStream PDFData)
         {
             // Clear response content & headers
             Response.Clear();
             Response.ClearContent();
             Response.ClearHeaders();
             Response.ContentType = "application/pdf";
             Response.Charset = string.Empty;
             Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
             Response.AddHeader("Content-Disposition", 
                 "attachment; filename=" + Title.Replace(" ", "").Replace(":", "-") + ".pdf");
            Response.OutputStream.Write(PDFData.GetBuffer(), 0, PDFData.GetBuffer().Length);
             Response.OutputStream.Flush();
             Response.OutputStream.Close();
             Response.End();
         }
    }

The MemoryStream is generated by calling the CreatePDF() method in my CustomReports class. It's a very simple report of 30 lines of text, divided into 2 groups. A bookmark is created for each group to simplify navigation in large reports. It has custom multiline header and custom footer displaying "Page X of Y".

using System;
 using System.IO;
 using System.Data;
 using System.Collections.Generic;
 using System.Text;
using iTextSharp.text;
 using iTextSharp.text.html.simpleparser;
 using iTextSharp.text.pdf;
namespace PDF_Tests
 {
     public class CustomReports
     {
        public MemoryStream CreatePDF(string Title)
         {
             MemoryStream PDFData = new MemoryStream();
             Document document = new Document(PageSize.LETTER, 50, 50, 80, 50);
             PdfWriter PDFWriter = PdfWriter.GetInstance(document, PDFData);
             PDFWriter.ViewerPreferences = PdfWriter.PageModeUseOutlines;
            // Our custom Header and Footer is done using Event Handler
             TwoColumnHeaderFooter PageEventHandler = new TwoColumnHeaderFooter();
             PDFWriter.PageEvent = PageEventHandler;
            // Define the page header
             PageEventHandler.Title = Title;
             PageEventHandler.HeaderFont = FontFactory.GetFont(BaseFont.COURIER_BOLD, 10, Font.BOLD);
             PageEventHandler.HeaderLeft = "Group";
             PageEventHandler.HeaderRight = "1";
            document.Open();
            for (int i = 1; i <= 2; i++)
             {
                 // Define the page header
                 PageEventHandler.HeaderRight = i.ToString();
                if (i != 1)
                 {
                     document.NewPage();
                 }
                // New outline must be created after the page is added
                 AddOutline(PDFWriter, "Group " + i.ToString(), document.PageSize.Height);
                for (int j = 1; j <= 30; j++)
                 {
                     Table ItemTable = new Table(2);
                     ItemTable.TableFitsPage = true;
                     ItemTable.Width = 95;
                     ItemTable.Offset = 0;
                     ItemTable.Border = 0;
                     ItemTable.DefaultCellBorder = 0;
                     ItemTable.AddCell(new Cell(string.Format("blah blah {0} - {1} ...", i, j)));
                     document.Add(ItemTable);
                     document.Add(new Paragraph("\r\n"));
                 }
            }
            document.Close();
            return PDFData;
         }
        public void AddOutline(PdfWriter writer, string Title, float Position)
         {
             PdfDestination destination = new PdfDestination(PdfDestination.FITH, Position);
             PdfOutline outline = new PdfOutline(writer.DirectContent.RootOutline, destination, Title);
             writer.DirectContent.AddOutline(outline, "Name = " + Title);
         }
     }
 }

Header and footer are created using a PageEventHandler class:

using System;
 using System.Collections.Generic;
 using System.Text;
using iTextSharp.text.pdf;
 using iTextSharp.text;
namespace PDF_Tests
 {
     public class TwoColumnHeaderFooter :PdfPageEventHelper
     {
         // This is the contentbyte object of the writer
         PdfContentByte cb;
        // we will put the final number of pages in a template
         PdfTemplate template;
        // this is the BaseFont we are going to use for the header / footer
         BaseFont bf = null;
        // This keeps track of the creation time
         DateTime PrintTime = DateTime.Now;
        #region Properties
         private string _Title;
         public string Title
         {
             get { return _Title; }
             set { _Title = value; }
         }
         
         private string _HeaderLeft;
         public string HeaderLeft
         {
             get { return _HeaderLeft; }
             set { _HeaderLeft = value; }
         }
        private string _HeaderRight;
         public string HeaderRight
         {
             get { return _HeaderRight; }
             set { _HeaderRight = value; }
         }
        private Font _HeaderFont;
         public Font HeaderFont
         {
             get { return _HeaderFont; }
             set { _HeaderFont = value; }
         }
        private Font _FooterFont;
         public Font FooterFont
         {
             get { return _FooterFont; }
             set { _FooterFont = value; }
         }
         #endregion
        // we override the onOpenDocument method
         public override void OnOpenDocument(PdfWriter writer, Document document)
         {
             try
             {
                 PrintTime = DateTime.Now;
                 bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                 cb = writer.DirectContent;
                 template = cb.CreateTemplate(50, 50);
             }
             catch (DocumentException de)
             {
             }
             catch (System.IO.IOException ioe)
             {
             }
         }
         
         public override void OnStartPage(PdfWriter writer, Document document)
         {
             base.OnStartPage(writer, document);
            Rectangle pageSize = document.PageSize;
            if (Title != string.Empty)
             {
                 cb.BeginText();
                 cb.SetFontAndSize(bf, 15);
                 cb.SetRGBColorFill(50, 50, 200);
                 cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetTop(40));
                 cb.ShowText(Title);
                 cb.EndText();
             }
            if (HeaderLeft + HeaderRight != string.Empty)
             {
                 PdfPTable HeaderTable = new PdfPTable(2);
                 HeaderTable.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE;
                 HeaderTable.TotalWidth = pageSize.Width - 80;
                 HeaderTable.SetWidthPercentage(new float[] { 45, 45 }, pageSize);
                 
                 PdfPCell HeaderLeftCell = new PdfPCell(new Phrase(8, HeaderLeft, HeaderFont));
                 HeaderLeftCell.Padding = 5;
                 HeaderLeftCell.PaddingBottom = 8;
                 HeaderLeftCell.BorderWidthRight = 0;
                 HeaderTable.AddCell(HeaderLeftCell);
                PdfPCell HeaderRightCell = new PdfPCell(new Phrase(8, HeaderRight, HeaderFont));
                 HeaderRightCell.HorizontalAlignment = PdfPCell.ALIGN_RIGHT;
                 HeaderRightCell.Padding = 5;
                 HeaderRightCell.PaddingBottom = 8;
                 HeaderRightCell.BorderWidthLeft = 0;
                 HeaderTable.AddCell(HeaderRightCell);
                cb.SetRGBColorFill(0, 0, 0);
                 HeaderTable.WriteSelectedRows(0, -1, pageSize.GetLeft(40), pageSize.GetTop(50), cb);
             }
         }
        public override void OnEndPage(PdfWriter writer, Document document)
         {
             base.OnEndPage(writer, document);
            int pageN = writer.PageNumber;
             String text = "Page " + pageN + " of ";
             float len = bf.GetWidthPoint(text, 8);
            Rectangle pageSize = document.PageSize;
            cb.SetRGBColorFill(100, 100, 100);
            cb.BeginText();
             cb.SetFontAndSize(bf, 8);
             cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30));
             cb.ShowText(text);
             cb.EndText();
            cb.AddTemplate(template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30));
             
             cb.BeginText();
             cb.SetFontAndSize(bf, 8);
             cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, 
                 "Printed On " + PrintTime.ToString(), 
                 pageSize.GetRight(40), 
                 pageSize.GetBottom(30), 0);
             cb.EndText();
         }
        public override void OnCloseDocument(PdfWriter writer, Document document)
         {
             base.OnCloseDocument(writer, document);
            template.BeginText();
             template.SetFontAndSize(bf, 8);
             template.SetTextMatrix(0, 0);
             template.ShowText("" + (writer.PageNumber - 1));
             template.EndText();
         }
    }
 }

Comments (18) -

Thx for this example. Worked like a charm.

Reply

Hi,
   your code is worked perfectly. Thank you for this code. But i have some  other requirement in my project. The Requirement is dragging an element in the page and after that i need print that elements in the PDF page and my all data is coming from database, so its not a static data. So is it possible in your code? my working domain is ASP.NET 2.0 and C#.
Its urgent...  
  

Reply


You are the Don !

Worked well, good clean explanatory examples  ...

Although i think the TwoHeaderAndFooter.cs example should come before the CustomReport ...  

Thanks

Reply

Thank U very much!!!

Reply

Hi, i have a doubt.Is there a way to get PDF embedded fonts and its type using itextsharp...

Reply

Hi,
I am newbie in C#. I am coding a mini windows forms application project for practise. Please could you help me how do i import this codes to my windows forms application project.
Youes sincerely.

Reply

Hi there,
Could you assist me with a problem I have, I am trying to structure my pdf layout page, inorder for a text/data to be center in the middle, and for it to stop when it reaches a certain point on the page, those points are where my footer and headers are located, but what it does now is to overwrite them, and either prints on top of the header image and pushes the footer image to a lower position than I had set it.

My vb code below:

Dim Headerpdf As Global.iTextSharp.text.Image = Global.iTextSharp.text.Image.GetInstance(HeaderImage)
                'Headerpdf.BorderWidth = 0.0F
                Headerpdf.ScaleAbsolute(574, 120)
                Headerpdf.Alignment = Global.iTextSharp.text.Image.ALIGN_TOP
                Headerpdf.SetAbsolutePosition(12, 705)


Dim Footerpdf As Global.iTextSharp.text.Image = Global.iTextSharp.text.Image.GetInstance(BottomImage)
                Footerpdf.ScaleToFit(90.0F, 200.0F)
                'Footerpdf.BorderWidth = 10.0F
                Footerpdf.ScalePercent(24.5F)
                'Footerpdf.SetAbsolutePosition(pdfDoc.PageSize.Width - 395.5F - 200.5F,
                'pdfDoc.PageSize.Height - 768.0F - 72.0F)
                Footerpdf.Alignment = Global.iTextSharp.text.Image.ALIGN_BOTTOM
                Footerpdf.SetAbsolutePosition(10.5, 0)


For i As Integer = 0 To 4 - 2
                    pdfDoc.Add(sidepdf)
                    pdfDoc.Add(Headerpdf)
                    pdfDoc.Add(table) ''carries the text/data that has to be printed on the page.
                    pdfDoc.Add(Footerpdf)
                Next

Reply

Hi,

I'm work on your POC to implement it with more functionality and possibilities.
I run into an issue with the page total. Here you use a PdfTemplate added to the DirectContent at specific position, though it works fine, in my case it doesn't allow me to manage my header/footer as I want.
I took up on your PdfPTable header and would like to insert the page total template into a PdfPCell.

Do you know if this is possible?
I checked the DirectContent output and can see where the template is inserted but I'd need to put it in a cell and when the cell is applied to the DirectContent, make it react like the original template.

Reply

Hi
Vielen Dank. dein Code war sehr hilfreich.

Mit freundlichen Grüßen aus Hamburg

Reply

Hi,
It worked very well. Thanks for the code.

Reply

Hi, This is very helpful. Thank you very much!

Reply

Thanks a ton for the article..

Reply

worked fine for me... thanks for this great help...

Reply

It worked for me. Thanks for sharing.

Reply

satheeshkumar

this line i am getting  float len = bf.GetWidthPoint(text, 8); object reference errror please give me any solution.
public override void OnEndPage(PdfWriter writer, Document document)
        {
            base.OnEndPage(writer, document);
            int pageN = writer.PageNumber;
            String text = "Page " + pageN + " of ";
            float len = bf.GetWidthPoint(text, 8);
            Rectangle pageSize = document.PageSize;
            cb.SetRGBColorFill(100, 100, 100);
            cb.BeginText();
            cb.SetFontAndSize(bf, 8);
            cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30));
            cb.ShowText(text);
            cb.EndText();
            cb.AddTemplate(template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30));

            cb.BeginText();
            cb.SetFontAndSize(bf, 8);
            cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT,
                "Printed On " + PrintTime.ToString(),
                pageSize.GetRight(40),
                pageSize.GetBottom(30), 0);
            cb.EndText();
        }

Reply

Hi. Thanks for the example. Basic question: what's the namespace for Table object in CreatePDF?
Thanks again.

Reply

thanks a lot

Reply

Thanks for this useful example.
What would you modify to print the footer only for the last page, being the footer a 4 columns table?
I have been trying to do it by myself to no avail.
Any help will be appreciated.

Reply

Add comment