Using iText to build PDF on the fly

Although there are many solutions (such as XML-FOP) to generate PDF on the fly, iText is a good choice to read PDF template and bind data dynamically.

1) For PDF form where data fields have fixed length, it is quite easy to use iText (I use C# version iTextSharp here) to bind data to PDF Text Field:

// Read PDF template
iTextSharp.text.pdf.PdfReader pdfRd = new iTextSharp.text.pdf.PdfReader(Server.MapPath("~/SampleJS.pdf"));
iTextSharp.text.pdf.PdfStamper stamp = new iTextSharp.text.pdf.PdfStamper(pdfRd, outputStream);

// Set form Text Fields
iTextSharp.text.pdf.AcroFields fields = stamp.AcroFields;
fields.SetField("formText", value);

// Close stamp
stamp.Close();

2) For free text data, you cannot put PDF Text Field to show data. For example, if you want to bind data to this template:

"Welcome to «Institution»! Please send mail to «Person» before «Date»"

You cannot use PDF Text Field because Text Field has fixed length. If «Institution» value is short, there will be extra blank space in the statement.

So what can you do? You can put the template statement into one Text Field with “Read Only” permission. Then you can replace the string with data like below:

// Get Text Fields from PDF file
iTextSharp.text.pdf.AcroFields fields = stamp.AcroFields;

// Get template
string formText = fields.GetField("formText");

// Replace template with data
formText = formText.Replace("«Institution»", txtInstitution);
formText = formText.Replace("«Person»", txtPerson);
formText = formText.Replace("«Date»", date);

// Set back the Text Field
fields.SetField("formText", formText);

3) How to insert image? PDF Text Field can be a placeholder for image. For example, to add a logo image to a placeholder:

// Get content to make changes
PdfContentByte overContent = stamp.GetOverContent(1);

// Get logo image
iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/logo.jpg"));

// Get logo placeholder position
float[] logoArea = fields.GetFieldPositions("Logo");

// Get logo rectangle
iTextSharp.text.Rectangle logoRect = new Rectangle(logoArea[1], logoArea[2], logoArea[3], logoArea[4]);

// Set logo position in the placeholder (right alignment)
logo.ScaleToFit(logoRect.Width, logoRect.Height);
logo.SetAbsolutePosition(logoArea[3] - logo.ScaledWidth + (logoRect.Width - logo.ScaledWidth) / 2, logoArea[2] + (logoRect.Height - logo.ScaledHeight) / 2);

// Add image
overContent.AddImage(logo);

4) How to add a barcode? Barcode is similar to image:

// Get content to make changes
PdfContentByte overContent = stamp.GetOverContent(1);

// Create a barcode
Barcode39 code39 = new Barcode39();
// Assign barcode value
code39.Code = barcodeValue;
code39.StartStopText = false;

// Create image from the barcode
iTextSharp.text.Image image39 = code39.CreateImageWithBarcode(overContent, null, null);

// Get barcode image placeholder
float[] barcodeArea = fields.GetFieldPositions("AppIDBarCode");
iTextSharp.text.Rectangle rect = new Rectangle(barcodeArea[1], barcodeArea[2], barcodeArea[3], barcodeArea[4]);
image39.ScaleToFit(rect.Width, rect.Height);
image39.SetAbsolutePosition(barcodeArea[1] + (rect.Width - image39.ScaledWidth) / 2, barcodeArea[2] + (rect.Height - image39.ScaledHeight) / 2);

// Add barcode image
overContent.AddImage(image39);

I still have several issues to solve, such as how to put rich text into Text Field. But for now, I have a good start for PDF generation. :)

9 comments:

Matt Ostanik said...

Jun,

We are seeking a consultant to assist us with developing a method for using iTextSharp to flatten annotations inside a PDF. I was wondering if you would have interest in helping us with this, or if you could recommend others who we could contact.

We need to be able to flatten all annotations inside a PDF. We have found that the setFreeTextFlattening method in iTextSharp will flatten text-based elements, but it does not apply to graphical annotations such as lines, shapes, revisions clouds, and stamps.

We will pay a consulting fee for assistance with this project. Please let me know if you could help or if you could recommend others who we could contact. Thank you.

Matt
Email: ostkm@yahoo.com

Anonymous said...

hi..pls help me .i am stuck in a problem
I am using the code below to generate a pdf file from an html file.I dont get any error in this code but the pdf file generated from this is blank/empty.
I hv tried so many times but no help.
Document test =new Document();
try
{
PdfWriter.GetInstance(test, new FileStream(Server.MapPath("test.pdf"), System.IO.FileMode.Create));

HtmlParser.Parse(test, Server.MapPath("test.html"));
}

}
catch (Exception err)
{
Response.Write(err.StackTrace);
Response.Write(err.Message);
}
Response.Redirect("http://localhost/WebRA/test.pdf");

pls help asap.its urgent.
thanx

Jun Meng said...

Hi roselin,

I have not used iTextSharp for a long time.

I am not sure how to use htmlParser. But if you could pass the content of the html to htmlParser, it has no problem to generate PDF file:

System.Xml.XmlTextReader xmlr = new System.Xml.XmlTextReader(new StringReader(@"<html><body>Test Only</body></html>"));

HtmlParser.Parse(document, xmlr);

Anonymous said...

Were you ever able to use Rich text with a text field in an existing PDF template or if you find any other way of inserting Rich text in the existing PDF template? I really need this quite urgently.
Your reply will be much appreciated.

Jun Meng said...

Ronnie,

Sorry, I did not try Rich text format in Textbox.

NightVision said...

Jun,

I have a signature image that I would like to insert into the IRS 1066 tax form but the 'signature' field is not exposed as a form field in the pdf although there is a space for someone to sign physically. I was wondering if there is a way to insert the signature image through iText.

Here is the pdf link
http://www.irs.gov/pub/irs-pdf/f1066.pdf

thanks in advance
--rk

Jun Meng said...

Hi rk,

You can use the similar process of adding image/barcode to insert signature to the PDF. That field is a PDF form field.

Even if you can not use the similar code, you can still use iText to insert signature using absolute position (x, y).

Anonymous said...

Hi, I want to get the annotation(only internal links) using itextsharp. How this can be achieved?
Please do the needful.

AdeleB said...

.NET Control for PDF-to-Text: how to build PDF from text file format