How to Create a Basic iText PDF Document with Graphics Using itextpdf Java Library

Overview

This article is meant as an introductory high level overview of iText Java library for creating PDF documents, as well as a showcase of some of the features I found to be really cool and useful. I will intertwine theoretical knowledge with the practical examples and let you see what was driving my decisions.

In the more technical part of this article I show you how to add text, links, images and generated graphics to your PDF document. So the end result will hopefully be that you get a good grasp of the iText API and will be able to start thinking about your future projects of generating PDFs as a part of your web service.

Although I will try to make my code as clear as poossible you would probably help your self greatly by knowing at least a little bit about Java.

Software You Need for This Exercice

  1. Java Runtime Environment - http://www.oracle.com/technetwork/java/javase/downloads/index.html (or just try http://www.oracle.com if the link above gets outdated)
  2. Integrated Development Environment - Eclipse - http://eclipse.org/downloads/
  3. iText library - http://itextpdf.com/download.php (click on the "Download iText" when you get there)

Why use iText?

The short answer is because you want to automate your PDF generation. A slightly longer answer is that you want to be able to produce high quality PDF documents
generated from an XML or a database. Plus "Google is using iText in the Google Calendar, Google Spreadsheets, Google Analytics...". Many other companies in the Business Intelligence & Reporting Tools world are using iText.

The most basic reason though is to produce documents that would look the same on all computers that can open a PDF document, which is not possible even today if you're using HTML. Also iText is very fast, has an unprecedented free support, (that some say is even better than paid support) with very active mailing list.

And in general the creation of iText is in my opinion an epic story in itself which deserves a separate reading session. Luckily Bruno Lowagie, the creator of iText, has been very active with creation, support and marketing of his great tool, so you'll be able to find a lot of information ranging from his biography, interviews, funny support related answers and of course much more.

Bruno Lowagie is one of those rare people that can be an open source pogrammer,
entrepreneur, marketer and all the while remain true to himself. I'm greatly
inspired by his story.

High Level Overview of the Sample Code

  1. Set up a document
  2. Add a Title
  3. Add a Subtitle
  4. Add a Paragraph of Text
  5. Add a Hyper Link
  6. Add a Click-able Image with a URL
  7. Add a Very Simple Pie-chart
  8. Helper Functions

If You Don't Understand Something or Want to Have More Examples Please Consider Buying One of the Books from Bruno Lowagie (iText in Action: Creating and Manipu

iText in Action: Creating and Manipulating PDF
iText in Action: Creating and Manipulating PDF

Imagine a publisher who wants to "stamp" his ebooks on the fly with the name of the buyer (to discourage sharing). Such a publisher would (and we know one who does) use iText for the task.

 
iText in Action: Covers iText 5
iText in Action: Covers iText 5

With iText, one can transform PDF documents into live, interactive applications quickly and easily. This free and open source library for Java and .NET is the leading tool of its kind, and was primarily developed and maintained by Bruno Lowagie, the author of this book.

 

Static Finals or Constants at the Top of iTextIntroduction Class

There is a bunch of static final variables defined at the top of my iTextIntroduction class. I have created them for myself and for you for easy tinkering. So feel free to change things up and generate different PDFs. I actually recommend doing this before getting your hands dirty with the code.

1 Set Up a Document

Calling setUpDocument(Document doc) from createPdf() method

The first six lines add meta data to the PDF document which can be seen from the File > Properties from inside the Acrobat Reader. The last three lines are related to the size and margins of the document. It is worth noting that the A4 standard of sheet size is equivalent to 210 millimeters by 297 millimeters which translates to about 605 by 855 points. This information will be important later on in this application and is generally good to know if you often word with PDF documents.

1 Set Up a Document Code Snippet

doc.addTitle( "Introduction to iText - " +
              "Create a PDF Document with Text, Hyperlinks and Graphics" );
doc.addSubject( "Introduction to iText" );
doc.addKeywords( "Java, PDF, iText" );
doc.addAuthor( "kievan" );
doc.addCreator( "kievan" );
// A4 = 210mm x 297mm ~ 605points x 855points
doc.setPageSize( PageSize.A4 );
doc.setMargins( 72f, 72f, 72f, 72f );

2 Add a Title

Calling addText( titleS, document, TITLE_FONT, 2 ) from createPdf() method


Here is a pretty simple function that adds a string of text to a document. The first line creates a paragraph using a string and a previously defined TITLE_FONT object. The second line calls a helper function that will add two new lines to the title object. And finally third line will add the title object to a doc object.

2 Add a Title Code Snippet

Paragraph paragraph = new Paragraph( text, font );
addEmptyLine( paragraph, newLines );
doc.add( paragraph );  

3 Add a Subtitle

Calling addText( titleS, document, TITLE_FONT, 2 ) from createPdf() method


A very similar scenario to the step above with the exception of the font object. By passing a different font object I changed the appearance of the subtitle string.

3 Add a Subtitle Code Snippet

Paragraph paragraph = new Paragraph( text, font );
addEmptyLine( paragraph, newLines );
doc.add( paragraph );  

4 Add a Paragraph of Text

Calling addText( String paragraphS, Document doc, Font font, int newLines ) from createPdf() method


Again the code reuse in action shows that we only change parameters to the same function. Again the only thing that changes is the font.

4 Add a Paragraph of Text Code Snippet

Paragraph paragraph = new Paragraph( text, font );
addEmptyLine( paragraph, newLines );
doc.add( paragraph ); 

If You Don't Understand Something or Want to Have More Examples Please Consider Buying One of the Books from Bruno Lowagie (iText in Action: Creating and Manipu

iText in Action: Creating and Manipulating PDF
iText in Action: Creating and Manipulating PDF

Imagine a publisher who wants to "stamp" his ebooks on the fly with the name of the buyer (to discourage sharing). Such a publisher would (and we know one who does) use iText for the task.

 
iText in Action: Covers iText 5
iText in Action: Covers iText 5

With iText, one can transform PDF documents into live, interactive applications quickly and easily. This free and open source library for Java and .NET is the leading tool of its kind, and was primarily developed and maintained by Bruno Lowagie, the author of this book.

 

5 Add a Hyper Link

Calling addURL( urlS, PARAGRAPH_URL, document, URL_FONT ) from createPdf() method

In this function we are faced with a slightly different situation. We are essentially adding a text that is hyperlinked to a URL. First I create an instance of Chunk object using its constructor. Then the Chunk c is assigned an action on line 2 (this is where the url is "built into" the text), and gets a decoration attribute added to it on line 3. And finally the Chunk c is added to the Document doc. The setUnderline takes two parameters of type float: line width and line y position.

5 Add a Hyper Link Code Snippet

Chunk c = new Chunk( text, font );
c.setAction( new PdfAction( new URL( url ) ) );
c.setUnderline(0.8f, -0.8f);
doc.add( c );

6 Add a Click-able Image with a URL

Calling addTextAtXY() and addImageAtXY( urlS, PARAGRAPH_URL, document, URL_FONT ) from createPdf() method

I will take a closer look at addTextAtXY() in the last step titled Helper Functions, as for right now the function does what the name suggests, it adds a string of text at the specified absolute location inside a document. addImageAtXY() has couple of extra wrinkles to make the image fit in nicely with the rest of the PDF document. iText PDF Library allows to scale and manipulate an image in different ways, which is very handy. On line 1 I am creating an Image instance called img, then I resize the image to 150 by 150 pixels or points (Note that I know the dimensions of the imported image before hand so I knew this would look ok, but if your image is not a square it might look malformed). Then I position the image on line 4 (Note that in iText the coordinate system's [0,0] coordinate is at the lower left corner of the page and, in case of A4 sized document, [605,855] is at the upper right corner!). I create an annotation on line 5 and on line 6 is where I add a link to an image by setting an annotation. Line 7 is where image is added to the document.

6 Add a Click-able Image with a URL Code Snippet

Image img = com.itextpdf.text.Image.getInstance( imageSource );
img.scaleToFit( 150f, 150f );
img.setAbsolutePosition( x, y );
Annotation anno = new Annotation( 0f, 0f, 0f, 0f, url ); 
img.setAnnotation( anno );
doc.add( img );

7 Add a Very Simple Pie-chart

Calling addTextAtXY( "Very simple pie chart.", writer.getDirectContent(), 260f, 305f ) and addPieChart( writer.getDirectContent() ) from createPdf() method

Again we'll take a closer at addTextAtXY in the next step, as for the addPieChart() this function is shamelessly simple. Basic idea is to use arcs to create equally sized pie segments.
First you'll see that I plan to update this function so it does all the things I've outlined in the TODO list.
Then on line 9 I set the width of line to be 3.2 points, right after on line 10 I set the color of the line to white. Line 12 is where the fill color is defined to a bright green. Then on line 13 there is a hint I've left for myself, which reads like this: lower left x, lower left y, upper right x, upper right y, starting angle in degrees, the extent of the arc segment in degrees. With that knowledge it is easier to understand line 14: we're drawing an arc bounded by the rectangle (I've made it a square) with lower left coordinates at 200,100 and upper right coordinates at 400,300 and that begins at angle 0 and extends for 120 degrees. Next line, 15, I'm drawing a line from where the arc method stopped drawing to the center of the future pie chart. At line 16, a method closePathFillStroke does two things at once: a line is drawn from the center of the pie chart to the beginning of the arc and then the pie piece is filled with predefined (line 12) color.
The rest of this function is just a repetition of lines 12 to 16. It most definitely not a way to create a pie, but for the purposes of understanding how iText draws simple shapes it is simpler to grasp.

7 Add a Very Simple Pie-chart Code Snippet

/** TODO: Automate and improve pie chart creation.
 *        1. Add support for adding pie pieces dynamically 
 *        from an ArrayList. 
 *        2. Calculate pie chart location based on single set
 *        of coordinates.
 *        3. Assign each pie piece a random color. 
 */

directcontent.setLineWidth(3.2f);
directcontent.setRGBColorStroke(255, 255, 255);

directcontent.setRGBColorFill(16, 205, 55);
// llx, lly, urx, ury, begin, extent
directcontent.arc(200, 100, 400, 300, 0, 120);
directcontent.lineTo(300,200);
directcontent.closePathFillStroke();

directcontent.setRGBColorFill(254, 205, 16);
directcontent.arc(200, 100, 400, 300, 120, 120);
directcontent.lineTo(300,200);
directcontent.closePathFillStroke();

directcontent.setRGBColorFill(155, 25, 16);
directcontent.arc(200, 100, 400, 300, 240, 120);
directcontent.lineTo(300,200);
directcontent.closePathFillStroke(); 

8 Helper Functions addTextAtXY()

Calling addTextAtXY( String text, PdfContentByte cb, float x, float y ) from various places in createPdf() method

On line 1 the Basefont object is created. Line 2, signaling a beginning of text generatoin on the current canvas (PdfContentByte cb). Line 3, setting the fill color, which sets the text color using of the predefined constants. Line 4, setting the font (font name [it is possible to use a font that you've downloaded to your system], encoding -> http://en.wikipedia.org/wiki/Windows-1252, and if its embedded or not, which means that if you use a font you've downloaded from somewhere iText can embed it in a PDF document; than the font looks the same on other machines even if they don't have it installed) and its size. Line 5 is where the absolute position of the text is set. Line 6 makes the text visible on the canvas, and line 7 indicates the end of text operations on canvas.

8 Helper Functions addTextAtXY() Code Snippet

BaseFont labelFont = BaseFont.createFont( BaseFont.TIMES_ROMAN, "Cp1252", true );
cb.beginText();
cb.setColorFill( TITLE_COLOR );
cb.setFontAndSize( labelFont, 10 );
cb.setTextMatrix( x, y );
cb.showText( text );
cb.endText();    	

8 Helper Functions addEmptyLine()

Calling addEmptyLine(Paragraph par, int howMany) from various places in createPdf() method

Line 1 is the start of a for loop which runs for as many times as specified by the howMany parameter. Line 2, adding an empty Paragraph to a Paragraph par.

8 Helper Functions addEmptyLine() Code Snippet

for( int i=0; i < howMany; i++ )
  par.add( new Paragraph(" ") );

If You Don't Understand Something or Want to Have More Examples Please Consider Buying One of the Books from Bruno Lowagie (iText in Action: Creating and Manipu

iText in Action: Creating and Manipulating PDF
iText in Action: Creating and Manipulating PDF

Imagine a publisher who wants to "stamp" his ebooks on the fly with the name of the buyer (to discourage sharing). Such a publisher would (and we know one who does) use iText for the task.

 
iText in Action: Covers iText 5
iText in Action: Covers iText 5

With iText, one can transform PDF documents into live, interactive applications quickly and easily. This free and open source library for Java and .NET is the leading tool of its kind, and was primarily developed and maintained by Bruno Lowagie, the author of this book.

 

Screenshot of the PDF generated by iTextIntroduction class

Screenshot of the PDF generated by iTextIntroduction class using iText PDF Java Library
Screenshot of the PDF generated by iTextIntroduction class using iText PDF Java Library | Source

iTextIntroduction.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import com.itextpdf.text.Annotation;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;

public class iTextIntroduction
{
  /** Path of the PDF document. */
  public static final String    OUTPUT          = 
  	"c:\\temp\\iTextIntorduction.pdf";
  /** Title color using rgb */
  public static final BaseColor TITLE_COLOR     = 
  	new BaseColor(25, 50, 75);
  /** Title font name, size, style and color */
  public static final Font      TITLE_FONT      = 
  	FontFactory.getFont( FontFactory.TIMES, 18, Font.BOLD, TITLE_COLOR );
  /** Subtitle font name, size, style and color */
  public static final Font      SUBTITLE_FONT   = 
  	FontFactory.getFont( FontFactory.TIMES, 16, Font.BOLD, TITLE_COLOR );
  /** Paragraph color using rgb */
  public static final BaseColor PARAGRAPH_COLOR = 
  	new BaseColor(75, 50, 75);
  /** Paragraph font name, size, style and color */
  public static final Font      PARAGRAPH_FONT  = 
  	FontFactory.getFont( FontFactory.TIMES, 12, Font.BOLD, PARAGRAPH_COLOR );
  /** URL color using rgb */
  public static final BaseColor URL_COLOR       = 
  	new BaseColor( 5, 5, 75);
  /** Paragraph font name, size, style and color */
  public static final Font      URL_FONT        = 
  	FontFactory.getFont( FontFactory.TIMES, 12, Font.BOLD, URL_COLOR );
  /** Url string to be added to a paragraph */
  public static final String    PARAGRAPH_URL   = 
  	"http://hubpages.com/profile/kievan";
  /** Url string of an image */
  public static final String    IMAGE_SRC_URL   = 
  	"http://s2.hubimg.com/u/3954873_177.jpg";
  /** Url string to be added to an image */
  public static final String    IMAGE_URL       = 
  	"http://hubpages.com/profile/kievan";
  
  
  public void createPdf(String output) throws IOException, DocumentException
  {

    // Create a document object
    Document document = new Document();  	
    
    // Create a writer that puts a document into a file
    FileOutputStream fos = new FileOutputStream( output );
    PdfWriter writer = PdfWriter.getInstance( document, fos );
  	


    document.open();
    
    // Set document size, margins and meta data
    setUpDocument( document );
    
    // Add a title 
    String titleS = "Introduction to iText - Create a PDF Document with " +
    								"Text, Hyperlinks and Graphics";
    addText( titleS, document, TITLE_FONT, 2 );
    
    // Add a subtitle
    String subtitleS = "iText rules!";    
    addText( subtitleS, document, SUBTITLE_FONT, 2 );
    
    // Add a paragraph
    String paragraphS = "A Sample text from me. Anything that comes to mind " +
    										"is simply written here. Where the mighty wind blows,"+
    										" there you shall find me.";
    addText( paragraphS, document, PARAGRAPH_FONT, 2 );

    // Add a URL
    String urlS = "- kievan";
    addURL( urlS, PARAGRAPH_URL, document, URL_FONT );

    // Add image with a label
    addTextAtXY( "Clickable HubPages profile picture.", writer.getDirectContent(), 225f, 530f );
    addImageAtXY( document, new URL( IMAGE_SRC_URL ), new URL( IMAGE_URL ), 225f, 370f );
    
    // Add pie chart
    addTextAtXY( "Very simple pie chart.", writer.getDirectContent(), 260f, 305f );
    addPieChart( writer.getDirectContent() );	    
        
    // Close a document
    document.close();
    
    System.out.println("Created PDF document!");
  	
  }
  
  /**
   * Sets up document size, margins and metadata.
   * iText allows to add metadata to the PDF which can be 
   * viewed in your Adobe Reader under File -> Properties
   * @param doc a document that is going to be set up.
   */
  public static void setUpDocument( Document doc ) 
  {
		doc.addTitle( "Introduction to iText - " +
				"Create a PDF Document with Text, Hyperlinks and Graphics" );
		doc.addSubject( "Introduction to iText" );
		doc.addKeywords( "Java, PDF, iText" );
		doc.addAuthor( "kievan" );
		doc.addCreator( "kievan" );
		// A4 = 210mm x 297mm ~ 605points x 855points
    doc.setPageSize( PageSize.A4 );
    doc.setMargins( 72f, 72f, 72f, 72f );
  }
  
  public static void addText( String text, Document doc, Font font, int newLines ) 
  throws DocumentException
  {
	  Paragraph paragraph = new Paragraph( text, font );
	  addEmptyLine( paragraph, newLines );
	  doc.add( paragraph );  
  }
  
  public static void addURL( String text, String url, Document doc, Font font ) 
  throws DocumentException, MalformedURLException
  {
	  Chunk c = new Chunk( text, font );
	  c.setAction( new PdfAction( new URL( url ) ) );
	  c.setUnderline(0.8f, -0.8f);
	  doc.add( c );
  }
  
  public static void addImageAtXY( Document doc, URL imageSource, URL url, float x, float y ) 
  throws DocumentException, IOException
  {
  	Image img = com.itextpdf.text.Image.getInstance( imageSource );
  	img.scaleToFit( 150f, 150f );
  	img.setAbsolutePosition( x, y );
  	Annotation anno = new Annotation( 0f, 0f, 0f, 0f, url ); 
  	img.setAnnotation( anno );
    doc.add( img );
  }
  
  /**
   * Draws the pie chart.
   * @param directcontent a canvas to which the pie chart has to be drawn.
   * @throws IOException 
   */
  public static void addPieChart(PdfContentByte directcontent) 
  throws DocumentException
  {        
    /** TODO: Automate and improve pie chart creation.
     *        1. Add support for adding pie pieces dynamically 
     *        from an Array or ArrayList. 
     *        2. Calculate pie chart location based on single set
     *        of coordinates.
     *        3. Assign each pie piece a random color. 
     */
  	
    directcontent.setLineWidth(3.2f);
    directcontent.setRGBColorStroke(255, 255, 255);
    
    directcontent.setRGBColorFill(16, 205, 55);
    // llx, lly, urx, ury, begin, extent
    directcontent.arc(200, 100, 400, 300, 0, 120);
    directcontent.lineTo(300,200);
    directcontent.closePathFillStroke();
    
    directcontent.setRGBColorFill(254, 205, 16);
    directcontent.arc(200, 100, 400, 300, 120, 120);
    directcontent.lineTo(300,200);
    directcontent.closePathFillStroke();
    
    directcontent.setRGBColorFill(155, 25, 16);
    directcontent.arc(200, 100, 400, 300, 240, 120);
    directcontent.lineTo(300,200);
    directcontent.closePathFillStroke();
  }
  
  /**
   * Adds text at an absolute position.
   * @param text a string of text to be added.
   * @param cb a canvas to which the text will be added.
   * @param x a position of the text along x axis.
   * @param y a position of the text along y axis.
   */
  public static void addTextAtXY( String text, PdfContentByte cb, float x, float y ) 
  throws IOException, DocumentException
  {
    BaseFont labelFont = BaseFont.createFont( BaseFont.TIMES_ROMAN, "Cp1252", true );
    cb.beginText();
    cb.setColorFill( TITLE_COLOR );
    cb.setFontAndSize( labelFont, 10 );
    cb.setTextMatrix( x, y );
    cb.showText( text );
    cb.endText();  	
  }
  
  /**
   * Adds empty line to a paragraph.
   * @param par a paragraph object to which line will be added.
   * @param howMany a number of empty lines to be added.
   */
  public static void addEmptyLine( Paragraph par, int howMany ) 
  throws DocumentException
  {
  	for( int i=0; i < howMany; i++ )
  		par.add( new Paragraph(" ") );
  }

  public static void main(String...args) 
  throws IOException, DocumentException
  {
  	new iTextIntroduction().createPdf( OUTPUT );
  }
  
}

More by this Author


Comments

No comments yet.

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working