You are on page 1of 13

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 a 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

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


1 doc.addTitle( "Introduction to iText - " +
2 "Create a PDF Document with Text, Hyperlinks and Graphics" );
3 doc.addSubject( "Introduction to iText" );
4 doc.addKeywords( "Java, PDF, iText" );
5 doc.addAuthor( "kievan" );
6 doc.addCreator( "kievan" );
7 // A4 = 210mm x 297mm ~ 605points x 855points
8 doc.setPageSize( PageSize.A4 );
9 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


1 Paragraph paragraph = new Paragraph( text, font );
2 addEmptyLine( paragraph, newLines );
3 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
1 Paragraph paragraph = new Paragraph( text, font );
2 addEmptyLine( paragraph, newLines );
3 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


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

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


1 Chunk c = new Chunk( text, font );
2 c.setAction( new PdfAction( new URL( url ) ) );
3 c.setUnderline(0.8f, -0.8f);
4 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


1 Image img = com.itextpdf.text.Image.getInstance( imageSource );
2 img.scaleToFit( 150f, 150f );
3 img.setAbsolutePosition( x, y );
4 Annotation anno = new Annotation( 0f, 0f, 0f, 0f, url );
5 img.setAnnotation( anno );
6 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


1 /** TODO: Automate and improve pie chart creation.
2 * 1. Add support for adding pie pieces dynamically
3 * from an ArrayList.
4 * 2. Calculate pie chart location based on single set
5 * of coordinates.
6 * 3. Assign each pie piece a random color.
7 */
8
9 directcontent.setLineWidth(3.2f);
10 directcontent.setRGBColorStroke(255, 255, 255);
11
12 directcontent.setRGBColorFill(16, 205, 55);
13 // llx, lly, urx, ury, begin, extent
14 directcontent.arc(200, 100, 400, 300, 0, 120);
15 directcontent.lineTo(300,200);
16 directcontent.closePathFillStroke();
17
18 directcontent.setRGBColorFill(254, 205, 16);
19 directcontent.arc(200, 100, 400, 300, 120, 120);
20 directcontent.lineTo(300,200);
21 directcontent.closePathFillStroke();
22
23 directcontent.setRGBColorFill(155, 25, 16);
24 directcontent.arc(200, 100, 400, 300, 240, 120);
25 directcontent.lineTo(300,200);
26 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",
1
true );
2
cb.beginText();
3
cb.setColorFill( TITLE_COLOR );
4
cb.setFontAndSize( labelFont, 10 );
5 cb.setTextMatrix( x, y );
6 cb.showText( text );
7 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


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

Screenshot of the PDF generated by iTextIntroduction


class
Screenshot of the PDF generated by iTextIntroduction class using iText PDF Java Library
Source: My Computer
iTextIntroduction.java
1 import java.io.FileOutputStream;
2 import java.io.IOException;
3 import java.net.MalformedURLException;
4 import java.net.URL;
5
6 import com.itextpdf.text.Annotation;
7 import com.itextpdf.text.BaseColor;
8 import com.itextpdf.text.Chunk;
9 import com.itextpdf.text.Document;
10 import com.itextpdf.text.DocumentException;
11 import com.itextpdf.text.Font;
12 import com.itextpdf.text.FontFactory;
13 import com.itextpdf.text.Image;
14 import com.itextpdf.text.PageSize;
15 import com.itextpdf.text.Paragraph;
16 import com.itextpdf.text.pdf.BaseFont;
17 import com.itextpdf.text.pdf.PdfAction;
18 import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
19
20
21 public class iTextIntroduction
22 {
23 /** Path of the PDF document. */
24 public static final String OUTPUT =
"c:\\temp\\iTextIntorduction.pdf";
25
/** Title color using rgb */
26
public static final BaseColor TITLE_COLOR =
27
new BaseColor(25, 50, 75);
28
/** Title font name, size, style and color */
29
public static final Font TITLE_FONT =
30
FontFactory.getFont( FontFactory.TIMES, 18, Font.BOLD, TITLE_COLOR );
31
/** Subtitle font name, size, style and color */
32
public static final Font SUBTITLE_FONT =
33
FontFactory.getFont( FontFactory.TIMES, 16, Font.BOLD, TITLE_COLOR );
34 /** Paragraph color using rgb */
35 public static final BaseColor PARAGRAPH_COLOR =
36 new BaseColor(75, 50, 75);
37 /** Paragraph font name, size, style and color */
38 public static final Font PARAGRAPH_FONT =
39 FontFactory.getFont( FontFactory.TIMES, 12, Font.BOLD, PARAGRAPH_COLOR
40 );
41 /** URL color using rgb */
42 public static final BaseColor URL_COLOR =
43 new BaseColor( 5, 5, 75);
44 /** Paragraph font name, size, style and color */
45 public static final Font URL_FONT =
46 FontFactory.getFont( FontFactory.TIMES, 12, Font.BOLD, URL_COLOR );
47 /** Url string to be added to a paragraph */
48 public static final String PARAGRAPH_URL =
49 "http://hubpages.com/profile/kievan";
50 /** Url string of an image */
51 public static final String IMAGE_SRC_URL =
52 "http://s2.hubimg.com/u/3954873_177.jpg";
53 /** Url string to be added to an image */
54 public static final String IMAGE_URL =
55 "http://hubpages.com/profile/kievan";
56
57
58 public void createPdf(String output) throws IOException,
59 DocumentException
60 {
61
62 // Create a document object
63 Document document = new Document();
64
65 // Create a writer that puts a document into a file
66 FileOutputStream fos = new FileOutputStream( output );
67 PdfWriter writer = PdfWriter.getInstance( document, fos );
68
69
70
71 document.open();
72
73 // Set document size, margins and meta data
74 setUpDocument( document );
75
76 // Add a title
77 String titleS = "Introduction to iText - Create a PDF Document with "
78 +
79 "Text, Hyperlinks and Graphics";
80 addText( titleS, document, TITLE_FONT, 2 );
81
82 // Add a subtitle
83 String subtitleS = "iText rules!";
84 addText( subtitleS, document, SUBTITLE_FONT, 2 );
85
86
// Add a paragraph
87
String paragraphS = "A Sample text from me. Anything that comes to
88 mind " +
89 "is simply written here. Where
90 the mighty wind blows,"+
91 " there you shall find me.";
92 addText( paragraphS, document, PARAGRAPH_FONT, 2 );
93
94 // Add a URL
95 String urlS = "- kievan";
96 addURL( urlS, PARAGRAPH_URL, document, URL_FONT );
97
98
// Add image with a label
99
addTextAtXY( "Clickable HubPages profile picture.",
100 writer.getDirectContent(), 225f, 530f );
101 addImageAtXY( document, new URL( IMAGE_SRC_URL ), new URL( IMAGE_URL ),
102 225f, 370f );
103
104
// Add pie chart
105
addTextAtXY( "Very simple pie chart.", writer.getDirectContent(),
106 260f, 305f );
107 addPieChart( writer.getDirectContent() );
108
109 // Close a document
110 document.close();
111
112 System.out.println("Created PDF document!");
113
114 }
115
116 /**
117 * Sets up document size, margins and metadata.
118 * iText allows to add metadata to the PDF which can be
119 * viewed in your Adobe Reader under File -> Properties
120 * @param doc a document that is going to be set up.
121 */
122 public static void setUpDocument( Document doc )
123 {
124 doc.addTitle( "Introduction to iText - " +
125 "Create a PDF Document with Text, Hyperlinks and Graphics"
126 );
127 doc.addSubject( "Introduction to iText" );
128 doc.addKeywords( "Java, PDF, iText" );
129 doc.addAuthor( "kievan" );
130 doc.addCreator( "kievan" );
131 // A4 = 210mm x 297mm ~ 605points x 855points
132 doc.setPageSize( PageSize.A4 );
133 doc.setMargins( 72f, 72f, 72f, 72f );
134 }
135
136 public static void addText( String text, Document doc, Font font, int
137 newLines )
138 throws DocumentException
139 {
140 Paragraph paragraph = new Paragraph( text, font );
141 addEmptyLine( paragraph, newLines );
142 doc.add( paragraph );
143 }
144
145 public static void addURL( String text, String url, Document doc, Font
146 font )
147 throws DocumentException, MalformedURLException
148 {
149 Chunk c = new Chunk( text, font );
150 c.setAction( new PdfAction( new URL( url ) ) );
151 c.setUnderline(0.8f, -0.8f);
152 doc.add( c );
153 }
154
155 public static void addImageAtXY( Document doc, URL imageSource, URL url,
156 float x, float y )
157 throws DocumentException, IOException
158 {
159 Image img = com.itextpdf.text.Image.getInstance( imageSource );
160 img.scaleToFit( 150f, 150f );
161 img.setAbsolutePosition( x, y );
162 Annotation anno = new Annotation( 0f, 0f, 0f, 0f, url );
img.setAnnotation( anno );
163 doc.add( img );
164 }
165
166 /**
167 * Draws the pie chart.
168 * @param directcontent a canvas to which the pie chart has to be drawn.
169 * @throws IOException
170 */
171 public static void addPieChart(PdfContentByte directcontent)
172 throws DocumentException
173 {
174 /** TODO: Automate and improve pie chart creation.
175 * 1. Add support for adding pie pieces dynamically
176 * from an Array or ArrayList.
177 * 2. Calculate pie chart location based on single set
178 * of coordinates.
179 * 3. Assign each pie piece a random color.
180 */
181
182 directcontent.setLineWidth(3.2f);
183 directcontent.setRGBColorStroke(255, 255, 255);
184
185 directcontent.setRGBColorFill(16, 205, 55);
186 // llx, lly, urx, ury, begin, extent
187 directcontent.arc(200, 100, 400, 300, 0, 120);
188 directcontent.lineTo(300,200);
189 directcontent.closePathFillStroke();
190
191 directcontent.setRGBColorFill(254, 205, 16);
192 directcontent.arc(200, 100, 400, 300, 120, 120);
193 directcontent.lineTo(300,200);
194 directcontent.closePathFillStroke();
195
196 directcontent.setRGBColorFill(155, 25, 16);
197 directcontent.arc(200, 100, 400, 300, 240, 120);
198 directcontent.lineTo(300,200);
199 directcontent.closePathFillStroke();
200 }
201
202 /**
203 * Adds text at an absolute position.
204 * @param text a string of text to be added.
205 * @param cb a canvas to which the text will be added.
206 * @param x a position of the text along x axis.
207 * @param y a position of the text along y axis.
208 */
209 public static void addTextAtXY( String text, PdfContentByte cb, float x,
210 float y )
211 throws IOException, DocumentException
212 {
213 BaseFont labelFont = BaseFont.createFont( BaseFont.TIMES_ROMAN,
214 "Cp1252", true );
215 cb.beginText();
216 cb.setColorFill( TITLE_COLOR );
217 cb.setFontAndSize( labelFont, 10 );
cb.setTextMatrix( x, y );
218 cb.showText( text );
219 cb.endText();
220 }
221
222 /**
223 * Adds empty line to a paragraph.
224 * @param par a paragraph object to which line will be added.
225 * @param howMany a number of empty lines to be added.
226 */
227 public static void addEmptyLine( Paragraph par, int howMany )
228 throws DocumentException
229 {
for( int i=0; i < howMany; i++ )
par.add( new Paragraph(" ") );
}

public static void main(String...args)


throws IOException, DocumentException
{
new iTextIntroduction().createPdf( OUTPUT );
}

You might also like