Massoud Mazar

Sharing The Knowledge

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"));
        }
        /// <summary>
        /// Sends a Stream of bytes to Client as a PDF file
        /// </summary>
        /// <param name="PDFData">Stream containing bytes</param>
        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 (13) -

  • HJensen

    1/12/2009 12:16:12 AM | Reply

    Thx for this example. Worked like a charm.

  • vinay

    2/16/2009 12:38:09 AM | 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...  
      

  • Aftab

    3/6/2009 1:32:13 AM | Reply


    You are the Don !

    Worked well, good clean explanatory examples  ...

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

    Thanks

  • Michal

    7/21/2009 11:57:01 AM | Reply

    Thank U very much!!!

  • bharath

    10/18/2009 11:21:29 PM | Reply

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

  • Ali Can

    9/26/2012 10:54:55 PM | 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.

  • Ndamu

    10/1/2012 6:53:41 PM | 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

  • Nick.T.

    1/23/2013 4:10:53 AM | 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.

  • Nasrin

    2/25/2013 3:29:34 AM | Reply

    Hi
    Vielen Dank. dein Code war sehr hilfreich.

    Mit freundlichen Grüßen aus Hamburg

  • Giridhar

    5/16/2013 1:37:11 AM | Reply

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

  • gopi

    5/16/2013 3:52:36 AM | Reply

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

  • Neo

    9/26/2014 5:42:32 AM | Reply

    Thanks a ton for the article..

  • Avinash

    10/29/2014 9:00:20 AM | Reply

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

Loading