Outputting to pdf using iTextSharp

Recently, I moved to Barclays. My job is still development, though. Totaljobs is a good company, and I enjoyed its casual, IT geek culture. It’s the thing I miss in my new job, as I work with quants.

The web application here has generally more complex UI. On public web page, you would not normally demand user to put in more than 20 textboxes or dropdowns. On financial application, it seems to be common. Nice graphs are often mandatory.

Anyway, one of my recent task was to let user download a report in pdf format. A colleague in the team told me we already used iTextSharp. I haven’t used it before, but it seems to be popular in java community, and ported to .Net as well. It looks like great component, but has poor documentation. It’s not easy to find good code examples.

One good working code is http://ozzieperez.net/blog/?p=255. I was lucky to find a code dealing with multi-columns and fixed column table. (http://www.mikesdotnetting.com/Article/89/iTextSharp-Page-Layout-with-Columns) This article greatly helped me.

I want to share my code too, to help other guys who may feel frustrated without any code sample. I changed variable names and also removed most part of the code, but it shouldn’t matter.


public class ExportService
{
    private const int LEFT = 0;
    private const int CENTER = 1;

    private pcService _pSvc;
    private BaseFont _verdanaBase;
    private Font _verdanaNormal, _verdanaHeading, _verdanaTitle;
    private BaseColor _textColor, _lineColor, _backgroundColor;

    public ExportService()
    {
        _pSvc = new pcService();

        _textColor = new BaseColor(ColorTranslator.FromHtml("#003366"));
        _lineColor = new BaseColor(ColorTranslator.FromHtml("#00a4e8"));
        _backgroundColor = new BaseColor(ColorTranslator.FromHtml("#eeeeee"));
        
        _verdanaBase = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED);
        _verdanaNormal = new Font(_verdanaBase, 10, Font.NORMAL, _textColor);
        _verdanaHeading = new Font(_verdanaBase, 12, Font.NORMAL, _textColor);
        _verdanaTitle = new Font(_verdanaBase, 24, Font.ITALIC, _textColor);
    }

    public MemoryStream GetPdfStream(int pcId, string logoPath)
    {
        var memoryStream = new MemoryStream();

        var pageSize = new Rectangle(PageSize.A4);
        var document = new Document(pageSize, 36, 36, 50, 50);

        SetMetadata(document);
        EncryptPdf(document, memoryStream);

        document.Open();
        
        document.Add(GetLogo(document, logoPath));

        var title = new Paragraph("Report", _verdanaTitle);
        title.SetAlignment("Center");

        document.Add(title);
        document.Add(new Paragraph("\n"));
        document.Add(new Paragraph("\n"));

        var table = GetTable(_pSvc.Get(pcId));
        document.Add(table);
        document.Close();

        return memoryStream;
    }

    private PdfPTable GetTable(Pc pc)
    {
        var table = new PdfPTable(4);
        var widths = new[] { 110f, 120f, 110f, 120f };
        table.TotalWidth = 460f;
        table.LockedWidth = true;
        table.SetWidths(widths);


        AddHeading(table, "Global Settings");
        AddCell(table, "Country: ", pc.OCountry, "Country: ", pc.OperatingAssetsCountry);
        AddCell(table, "Currency: ", pc.Currency, "Date: ", pc.ValuationDateString);

        AddHeading(table, "Customer");
        AddCell(table, "Customer Name: ", pc.Customer.Name, "Customer ID: ", pc.Customer.Id.ToString());
        AddCell(table, "Bc: ", pc.Customer.Bc.ToString(), "Sales Turnover (m): ", pc.Customer.Sales.TwoDpText());

        ...

        AddHeading(table, "Valuation Identification Number: " + pc.Id);
        return table;
    }

    private void AddHeading(PdfPTable table, string heading)
    {
        PdfPCell cell = new PdfPCell(new Phrase(heading, _verdanaHeading));
        cell.Colspan = 4;
        cell.BackgroundColor = _backgroundColor;
        cell.HorizontalAlignment = CENTER;
        cell.Border = iTextSharp.text.Rectangle.BOX;
        cell.BorderColor = _lineColor;
        cell.MinimumHeight = 22;
        cell.VerticalAlignment = 1;
        table.AddCell(cell);
    }

    private void AddCell(PdfPTable table, string label1, string text1, string label2, string text2)
    {
        var labelCell = GetLabelCell();
        var textCell = GetTextCell();

        labelCell.Phrase = new Phrase(label1, _verdanaNormal);
        table.AddCell(labelCell);

        textCell.Phrase = new Phrase(text1, _verdanaNormal);
        table.AddCell(textCell);

        labelCell.Phrase = new Phrase(label2, _verdanaNormal);
        table.AddCell(labelCell);

        textCell.Phrase = new Phrase(text2, _verdanaNormal);
        table.AddCell(textCell);
    }

    private void AddCell(PdfPTable table, string label, string text)
    {
        var labelCell = GetLabelCell();
        var textCell = GetTextCell();

        labelCell.Phrase = new Phrase(label, _verdanaNormal);
        table.AddCell(labelCell);

        textCell.Phrase = new Phrase(text, _verdanaNormal);
        table.AddCell(textCell);

        labelCell.Phrase = new Phrase(string.Empty, _verdanaNormal);
        table.AddCell(labelCell);

        textCell.Phrase = new Phrase(string.Empty, _verdanaNormal);
        table.AddCell(textCell);
    }

    private PdfPCell GetTextCell()
    {
        return new PdfPCell
                   {
                       Border = Rectangle.RIGHT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.TOP_BORDER,
                       BorderColor = _lineColor,
                       MinimumHeight = 20,
                       HorizontalAlignment = LEFT,
                   };
    }

    private PdfPCell GetLabelCell()
    {
        return new PdfPCell
                   {
                       Border = Rectangle.LEFT_BORDER | Rectangle.BOTTOM_BORDER | Rectangle.TOP_BORDER,
                       BorderColor = _lineColor,
                       MinimumHeight = 20,
                       HorizontalAlignment = LEFT,
                       PaddingLeft = 3
                   };
    }

    private Image GetLogo(Document document, string logoPath)
    {
        var logo = Image.GetInstance(logoPath);
        logo.ScalePercent(48f);
        logo.SetAbsolutePosition(document.PageSize.Width - 36f - 130f, document.PageSize.Height - 36f - 15.36f);
        return logo;
    }

    private void SetMetadata(Document document)
    {
        document.AddAuthor("Wordpress");
        document.AddSubject("Report");
        document.AddKeywords("Report;Wordpress");
    }

    private void EncryptPdf(Document document, MemoryStream memoryStream)
    {
        var writer = PdfWriter.GetInstance(document, memoryStream);
        writer.SetEncryption(PdfWriter.STRENGTH128BITS, null, null, PdfWriter.AllowCopy | PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_SCREENREADERS);
    }

}
Outputting to pdf using iTextSharp