<img alt="" src="https://secure.leadforensics.com/150446.png " style="display:none;">
Go to top icon

Dynamic Generation of PDF File Using iTextSharp

Sagar Damle Oct 31, 2017

iTextSharp

Dynamic generation of PDF file using iTextSharp.jpg
Many a times, we need to generate PDF files at runtime in our application. Here, 'iTextSharp' (a third party DLL) can help us to do the job. Generally, we need to export/create the documents such as reports or invoices in PDF format. These documents are in tabular form. In this blog, I would like to show some basics of creating tables in PDF using 'iTextSharp' along with the common errors that I have faced.

You can either
  • Download the complete zip file from web (https://sourceforge.net/projects/itextsharp/), extract it to get itextsharp.dll, copy this DLL in your project and add its reference in "References"
    OR
  • Directly install from nuget (https://www.nuget.org/packages/iTextSharp/).
Let's create an MVC application for demonstration purpose. (I am using VS 2015 Express edition for Web.)

  • Open Visual Studio and create a new empty MVC application.
(File → New Project... → Select “Web” as a type of project under “C#” → Enter name for your web application (PDFDemo) → Click “OK” to navigate to next window → Select “Empty” as a template type with check marked checkbox for “MVC” → Click “OK”)

  • Install iTextSharp using package manager console.
    • Tools → NuGet Package Manager → Package Manager Console
    • Execute this command : Install-Package iTextSharp -Version {version_number}

(For the latest {version_number}, please refer this link -

https://www.nuget.org/packages/iTextSharp/

I am using version 5.5.12 of the DLL. So the command becomes -
Install-Package iTextSharp -Version 5.5.12)
You can check if the reference to itextsharp.dll is added to "References" in the project once installation is complete.

Instead of using package manager console for installation, you can also browse for the DLL by going to -
Tools → NuGet Package Manager → Manage NuGet Packages for Solution…
and install it from there.

  • Create a new folder named "Home" inside "Views" folder. Add a new view ("Index.cshtml") with an empty template and without using any layout page in this newly created "Home" folder.
Replace the default code in the file with the code given below -

@{
Layout = null;
}

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create Sample PDF</title>
</head>
<body>
<div style="padding: 20px;">
@Html.ActionLink("Download Sample PDF", "DownloadPDF", "Home")
</div>
</body>
</html>

  • Add a new empty controller ("HomeController.cs") inside "Controllers" folder.
Replace its original content with this one -

using System.Web.Mvc;
using iTextSharp.text.pdf;
using iTextSharp.text;
using System.IO;
using System.Drawing;

namespace PDFDemo.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}

public FileResult DownloadPDF()
{
byte[] byteArray;

using (var stream = new MemoryStream())
{
Document doc = new Document(PageSize.A4); //Create new PDF document of A4 size.
var pdfWriter = PdfWriter.GetInstance(doc, stream); //Get a "writer" to write into the document (as like we use a pen to write on a paper) and keep the document into MemoryStream()

doc.Open();

PdfPTable tbl = new PdfPTable(2); //Create a table with 2 columns
tbl.SetWidths(new[] { 25, 75 }); //Set relative widths of the columns. Here, Width of 2nd column = 3 * (Width of 1st column)
tbl.WidthPercentage = 100.0f; //Allow the table to take up the full width available (after applying default margins for A4 sized paper - Because I haven't set any margins explicitly!)

//Row 1
PdfPCell cell = new PdfPCell(new Phrase("Simple Present Tense"));
ApplyPrintSettingsToCell(cell);
tbl.AddCell(cell);

cell = new PdfPCell(new Phrase("I write a letter."));
ApplyPrintSettingsToCell(cell);
tbl.AddCell(cell);

//Row 2
cell = new PdfPCell(new Phrase("Simple Past Tense"));
ApplyPrintSettingsToCell(cell);
tbl.AddCell(cell);

cell = new PdfPCell(new Phrase("I wrote a letter."));
ApplyPrintSettingsToCell(cell);
tbl.AddCell(cell);

//Row 3
cell = new PdfPCell(new Phrase("Simple Future Tense"));
ApplyPrintSettingsToCell(cell);
tbl.AddCell(cell);

cell = new PdfPCell(new Phrase("I will write a letter."));
ApplyPrintSettingsToCell(cell);
tbl.AddCell(cell);

doc.Add(tbl);
doc.Close();

byteArray = stream.ToArray();
return File(byteArray, "application/pdf", "Simple Tense.pdf");
}
}

private void ApplyPrintSettingsToCell(PdfPCell pCell)
{
pCell.PaddingLeft = 5.0f;
pCell.HorizontalAlignment = PdfPCell.ALIGN_LEFT;
pCell.VerticalAlignment = PdfPCell.ALIGN_MIDDLE;
pCell.UseAscender = true; //Setting [UseAscender] property to "true" along with setting [VerticalAlignment] to "PdfPCell.ALIGN_MIDDLE" helps to align the text in the cell at vertically middle position.
}
}
}

  • And that's it! Now run the application. You can download the sample PDF file by clicking on the link "Download Sample PDF"!
Things to remember-

  • Do not forget to create an instance of PdfWriter() because otherwise we can't write anything in the PDF. Similarly, don't forget to add doc.Add(tbl) statement which places an instance of PdfPTable() in the document.
  • (This is the most frequent error that I have experienced in my coding!)
    For PdfPTable(int numColumns) overload of PdfPTable() constructor, the effective total number of cells in the PdfPTable() must be N or in multiples of N,
where N = Number of columns declared at the time of creating instance of PdfPTable()

Please let me elaborate the point.
The following program will throw an exception -

public FileResult DownloadPDF()
{
byte[] byteArray;

using (var stream = new MemoryStream())
{
Document doc = new Document(PageSize.A4);
var pdfWriter = PdfWriter.GetInstance(doc, stream);

doc.Open();

PdfPTable tbl = new PdfPTable(2);
tbl.SetWidths(new[] { 25, 75 });
tbl.WidthPercentage = 100.0f;

PdfPCell cell = new PdfPCell(new Phrase("Simple Present Tense"));
cell.PaddingLeft = 5.0f;
cell.HorizontalAlignment = PdfPCell.ALIGN_LEFT;
cell.VerticalAlignment = PdfPCell.ALIGN_MIDDLE;
cell.UseAscender = true;
tbl.AddCell(cell);

doc.Add(tbl);
doc.Close();

byteArray = stream.ToArray();
return File(byteArray, "application/pdf", "Simple Tense.pdf");
}
}

The reason is - I have declared PdfPTable() for 2 columns and am inserting only 1 cell into it. Here, the total number of cells should be 2 or in multiples of 2 (that is - 2,4,6 and so on.)
Let's check for this one -

public FileResult DownloadPDF()
{
byte[] byteArray;

using (var stream = new MemoryStream())
{
Document doc = new Document(PageSize.A4);
var pdfWriter = PdfWriter.GetInstance(doc, stream);

doc.Open();

PdfPTable tbl = new PdfPTable(2);
tbl.SetWidths(new[] { 25, 75 });
tbl.WidthPercentage = 100.0f;

PdfPCell cell = new PdfPCell(new Phrase("Simple Present Tense"));
cell.PaddingLeft = 5.0f;
cell.HorizontalAlignment = PdfPCell.ALIGN_LEFT;
cell.VerticalAlignment = PdfPCell.ALIGN_MIDDLE;
cell.UseAscender = true;
cell.Colspan = 2;
tbl.AddCell(cell);

doc.Add(tbl);
doc.Close();

byteArray = stream.ToArray();
return File(byteArray, "application/pdf", "Simple Tense.pdf");
}
}

Now the code is working fine. It's due to the statement -
cell.Colspan = 2;

By setting Colspan property to 2, I am making effective number of cells in the table equal to 2. (Please also check for Rowspan property of PdfPCell() on web which is also helpful in designing the table for required structure.)

I hope you have enjoyed my writing! This is just a basic program using iTextSharp. There is a lot to explore and try on your own. Have fun!

e-Zest is a leading digital innovation partner for enterprises and technology companies that utilizes emerging technologies for creating engaging customers experiences. Being a customer-focused and technology-driven company, it always helps clients in crafting holistic business value for their software development efforts. It offers software development and consulting services for cloud computing, enterprise mobility, big data and analytics, user experience and digital commerce.