iText Tutorial SourceForge.net Logo iText, a Free Java-PDF library
by
Bruno Lowagie
[Home]   [TOC] [Next] [PDF]

Part I: Simple iText

Chapter 1: Creating a document
Creation of a document in 5 steps: Hello World
Download the source code of the first example: Chap0101.java.
This example contains the 5 most important steps to create a PDF file using iText:

Step 1:
Creates an instance of the com.lowagie.text.Document-object:
Document document = new Document();

Step 2:
Creates a Writer that listens to this document and writes the document to the OutputStream of your choice:
PdfWriter.getInstance(document, new FileOutputStream("Chap0101.pdf"));

Step 3:
Opens the document:
document.open();

Step 4:
Adds content to the document:
document.add(new Paragraph("Hello World"));

Step 5:
Closes the document:
document.close();

Check the result here: Chap0101.pdf.

Examining step 1: the Document-object
The com.lowagie.text.Document-object has 3 constructors:

public Document();
public Document(Rectangle pageSize);
public Document(Rectangle pageSize,
   int marginLeft,
   int marginRight,
   int marginTop,
   int marginBottom);

The first constructor calls the second one, with PageSize.A4 as parameter.
The second constructor calls the third one, with 36 as value for each margin.

PageSize
You could create your own Rectangle-object in a certain color and use this as pageSize.
In example Chap0102.java, we create a long, narrow document with a yellowish backgroundcolor:
Rectangle pageSize = new Rectangle(144, 720);
pageSize.setBackgroundColor(new java.awt.Color(0xFF, 0xFF, 0xDE));
Document document = new Document(pageSize);

This is the result: Chap0102.pdf. Normally, you don't have to worry about creating this rectangle, since you can use one of the statics in class PageSize.java. These are the pagesizes that are provided: A0-A10, LEGAL, LETTER, HALFLETTER, _11x17, LEDGER, NOTE, B0-B5, ARCH_A-ARCH_E, FLSA and FLSE.

Most these pageSizes are in PORTRAIT-format. If you want them to be in LANDSCAPE, all you have to do is rotate() the Rectangle:
Document document = new Document(PageSize.A4.rotate());
Check out example Chap0103.java and its result.

Margins
When creating a document, you can also define left, right, upper and lower margins:
Document document = new Document(PageSize.A5, 36, 72, 108, 180);
In example Chap0104.java (and its result: Chap0104.pdf), you will see that this document has a left margin of 0.5 inch and a right margin of 1 inch. The upper margin is 1.5 inch, the lower 2.5 inch.

Measurements
When creating a rectangle or choosing a margin, you might wonder what measurement unit is used: centimeters, inches or pixels. In fact, the default measurement system roughly corresponds to the various definitions of the typographic unit of measurement known as the point. There are 72 points in 1 inch.
If you want to create a rectangle in PDF that has the size of an A4-page, you have to calculate the number of points:
   21 cm / 2.54 = 8.2677 inch
   8.2677 * 72 = 595 points
   29.7 cm / 2.54 = 11.6929 inch
   11.6929 * 72 = 842 points
The default border of 36 points corresponds with half an inch.

Remark: if you change the page size, this only has effect on the next page (see page initialisations). If you change the margins, this has an immediate effect, so be careful!

Examining step 2: the Writer-object
Once our document is created, we can create one or more instances of writers that listen to this document. All writers should be derived from the abstract class com.lowagie.text.DocWriter.
For the moment there are two possibilities: you can use com.lowagie.text.pdf.PdfWriter to generate documents in the Portable Document Format, or you can use com.lowagie.text.html.HtmlWriter to generate documents in HTML. If for instance you want to generate TeX-documents as well, you could write a package: com.lowagie.text.TeX.TeXWriter.

Remark:
I wrote the HTML classes only for testing purposes. You really shouldn't use them in a production environment. The resulting HTML isn't very nice and there are lots of better tools around. The iText HTML-package can be useful for debugging reasons. HTML is a lot more straightforward than PDF. When an error occurs while generating a PDF file, it is very hard to find what bug caused the error. The resulting PDF-file is too damaged to examin its contents. So while testing I always generate an HTML file at the same time in order to retrieve the exact place where the error occurs or the exact object that throws the exception.
There is also a package com.lowagie.text.xml and a package com.lowagie.text.rtf, but the XML and RTF generation functionality isn't that stable yet (see Chapter 7 and Chapter 8).

The constructor of these writer-classes is made private. You can only create an instance with the following method:
public static xxxWriter getInstance(Document document, OutputStream os) throws DocumentException
(xxx being Pdf or Html)

You can create an instance this way:
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("Chap01xx.pdf"));
but you will hardly ever need the object writer (except if you want to create Advanced PDF or if you want to use some very specific functionalities such as ViewerPreferences or Encryption). So it's sufficient to just get the instance:
PdfWriter.getInstance(document, new FileOutputStream("Chap01xx.pdf"));

It's trivial that the first parameter should be the document you created in step 1.
The second parameter can be an outputStream of any kind.
Until now, we have always used a java.io.FileOutputStream to write the document to a file, but in example Chap0105, the outputStream is a javax.servlet.ServletOutputStream. (This is not a standalone example; you will have to test this code on a Servlet Engine).
If you use MSIE as browser, you will only see a blank page due to a bug in some specific versions of MicroSofts browser (see the FAQ). This has been discussed over and over in the mailing list archives and even in the newsgroup comp.text.pdf. If you want to try a more difficult example (using the workaround in the FAQ), try the following code: Calendar.java and Month.java.
A JSP example was provided by Tal Liron: pdf.jsp.


Examining step 3: Meta data + opening the document
Metadata
Before you add any actual data (= content), you might want to add some metadata about the document with one of these methods:
public boolean addTitle(String title)
public boolean addSubject(String subject)
public boolean addKeywords(String keywords)
public boolean addAuthor(String author)
public boolean addCreator(String creator)
public boolean addProducer()
public boolean addCreationDate()
public boolean addHeader(String name, String content)

You can choose your own title, subject, keywords, author and creator, but the method that adds the producerdata should always add:
iText (or a reference to iText) and the method that adds the creation date always add the current system time (as a matter of fact, these two methods are called automatically).
You can also add a header with a custom name, but this will have no effect on the PdfWriter (for the moment it is only used in the HtmlWriter).
If we look at the example in step 1: Chap0101.pdf, we see that only the producer and date are shown in the infobox. If we run Chap0106.java, the result is a similar document: Chap0106.pdf, but there are more items added to the infobox:
info
info

As an additional illustration of the fact that you can send documents to any outputstream; example 6 sends HTML to System.out.
System.out

You can see that a custom header was used to add an 'Expires' META-tag.
There is 1 exception: if you add a custom header with as name HtmlWriter.STYLESHEET, you get a link to a stylesheet:
document.add(new Header(HtmlWriter.STYLESHEET, "my.css"));
results in: <link rel="STYLESHEET" type="text/css" href="my.css">

Things to do BEFORE you open the document
You can only add metadata BEFORE the open-method is invoked. This is a choice made by the developer of iText.
In HTML meta-information is put between the HEAD-tags at the beginning of the document (the header section). Invoking the open-method causes the writer to write this header to the OutputStream. So there is no way to change this data once the document is 'opened'.
The PDF header doesn't contain any metadata, it looks like this:
   %PDF-1.2
   %рсту

The first line indicates the generated document is a file in the Portable Document Format version 1.2.
The meaning of the second line is explained in the reference manual.
Portable Document Format Reference Manual Version 1. 3 (section 2.3.2 'Portability' page 22):
A PDF file is a binary file; the entire 8-bit range of characters may be used. Unfortunately, some agents treat files that happen to use only the printable subset of the 7-bit ASCII code and whitespace characters as text, and take unreasonable liberties with the contents. For example, mail-transmission systems may not preserve certain 7-bit characters and may change line endings. This can cause damage to PDF files.
Therefore, in situations where it is possible to label PDF files as binary, we recommend that this be done. One method for encouraging such treatment is to include a few binary characters (codes greater than 127) in a comment near the beginning of the file.
In PDF, the metadata is kept in a PdfInfo-object, written to the PdfWriter when the document is closed. So there is no technical reason why one couldn't alter the library to be able to add or change the metadata at any time. It's a design choice that was made.

Page initialisations
The open-method also triggers some initialisations in the different writers. For instance if you want a Watermark or a HeaderFooter-object to appear starting on the FIRST page of the document, you have to add it BEFORE you open the document. The same goes for setting watermark, headers, footers, pagenumbers and sizes for the rest of the pages in the document.
When you invoke methods such as:
public boolean setPageSize(Rectangle pageSize)
public boolean add(Watermark watermark)
public void removeWatermark()
public void setHeader(HeaderFooter header)
public void resetHeader()
public void setFooter(HeaderFooter footer)
public void resetFooter()
public void resetPageCount()
public void setPageCount(int pageN)
the result of these methods will only be seen on the next new page (when the initialisation methods of this page are called). This is illustrated in example 7. If you want to try this example, you will need an image file called watermark.jpg. The result should look like Chap0107.pdf.

Viewerpreferences
For PDF files you can also set some viewer preferences with the method:
public void setViewerPreferences(int preferences)

In example 8, some of the possibilities are demonstrated:
writerA.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft);
(see Chap0108a.pdf)
writerB.setViewerPreferences(PdfWriter.HideMenubar | PdfWriter.HideToolbar);
(see Chap0108b.pdf)
writerC.setViewerPreferences(PdfWriter.PageLayoutTwoColumnLeft | PdfWriter.PageModeFullScreen | PdfWriter.NonFullScreenPageModeUseThumbs);
(see Chap0108c.pdf)
As you can see, the preferences can be set by ORing some of these constants:
  • The page layout to be used when the document is opened (choose one).
    • PdfWriter.PageLayoutSinglePage - Display one page at a time.
    • PdfWriter.PageLayoutOneColumn - Display the pages in one column.
    • PdfWriter.PageLayoutTwoColumnLeft - Display the pages in two columns, with oddnumbered pages on the left.
    • PdfWriter.PageLayoutTwoColumnRight - Display the pages in two columns, with oddnumbered pages on the right.
  • The page mode how the document should be displayed when opened (choose one).
    • PdfWriter.PageModeUseNone - Neither document outline nor thumbnail images visible.
    • PdfWriter.PageModeUseOutlines - Document outline visible.
    • PdfWriter.PageModeUseThumbs - Thumbnail images visible.
    • PdfWriter.PageModeFullScreen - Full-screen mode, with no menu bar, window controls, or any other window visible.
  • PdfWriter.HideToolbar - A flag specifying whether to hide the viewer application's tool bars when the document is active.
  • PdfWriter.HideMenubar - A flag specifying whether to hide the viewer application's menu bar when the document is active.
  • PdfWriter.HideWindowUI - A flag specifying whether to hide user interface elements in the document's window (such as scroll bars and navigation controls), leaving only the document's contents displayed.
  • PdfWriter.FitWindow - A flag specifying whether to resize the document's window to fit the size of the first displayed page.
  • PdfWriter.CenterWindow - A flag specifying whether to position the document's window in the center of the screen.
  • The document's page mode, specifying how to display the document on exiting full-screen mode. It is meaningful only if the page mode is PageModeFullScreen (choose one).
    • PdfWriter.NonFullScreenPageModeUseNone - Neither document outline nor thumbnail images visible
    • PdfWriter.NonFullScreenPageModeUseOutlines - Document outline visible
    • PdfWriter.NonFullScreenPageModeUseThumbs - Thumbnail images visible
Remark: you can invoke this method only on a class of type PdfWriter.

Encryption
Another thing to do BEFORE you open the document, is to set the encryption (that is: if you want the PDF file to be encrypted). To achieve this, you use the method:
public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions);

  • The strength is one of these two constants:
    • PdfWriter.STRENGTH40BITS: 40 bits
    • PdfWriter.STRENGTH128BITS: 128 bits (only with Acrobat Reader 5.0 or higher)
  • The userPassword and ownerPassword can be null or have zero length. In this case the ownerPassword is replaced by a random string.
  • Permissions are set by ORing some of these constants:
    • PdfWriter.AllowPrinting
    • PdfWriter.AllowModifyContents
    • PdfWriter.AllowCopy
    • PdfWriter.AllowModifyAnnotations
    • PdfWriter.AllowFillIn
    • PdfWriter.AllowScreenReaders
    • PdfWriter.AllowAssembly
    • PdfWriter.AllowDegradedPrinting
This functionality is demonstrated in example 9 and example 10.

writer.setEncryption(PdfWriter.STRENGTH40BITS, null, null, PdfWriter.AllowCopy);
Chap0109.pdf can be opened without using a password, but the user is not allowed to Print, Modify,... the document.

writer.setEncryption(PdfWriter.STRENGTH128BITS, "userpass", "ownerpass", PdfWriter.AllowCopy | PdfWriter.AllowPrinting);
When you try to open Chap0110.pdf, you are asked for a password (type in 'userpass'). Because the AllowPrinting-preference was added, you can print this document without any problem.


Examining step 4: adding content
In the different examples explaining step 1 to 3, you have already encountered objects such as Phrase, Paragraph,... In the next 5 chapters all these objects will be explained more thoroughly.
It is very important to realize that not all types of objects are supported in all types of writers. For instance: the Graphic-object isn't supported in HTML. If you add a graphic to a Document, the listening HtmlWriter will ignore this.
Sometimes you may want a writer to deliberately ignore actions performed on a document. This is shown in example 11.
If we create two writers: writerA and writerB (this is an exception to what was said in step 2):
PdfWriter writerA = PdfWriter.getInstance(document, new FileOutputStream("Chap0111a.pdf"));
PdfWriter writerB = PdfWriter.getInstance(document, new FileOutputStream("Chap0111b.pdf"));
We can create two documents that are slightly different:
writerA.pause();
document.add(new Paragraph("This paragraph will only be added to Chap0111b.pdf, not to Chap0111a.pdf"));
writerA.resume();
You can compare the results of example 11 here: Chap0111a.pdf vs. Chap0111b.pdf.


Examining step 5: closing the document
Closing the document is very important, because it flushes and closes the outputstream to which the writer is writing. The close-method is called in the finalize-method, but you shouldn't count on that. You should always close the document yourself!



[Top]   [TOC] [Next] [PDF]
Page Updated: $Date: 2003/06/25 07:36:34 $
Copyright © 2000, 2001 by Bruno Lowagie
Adolf Baeyensstraat 121, 9040 Gent, BELGIUM,
tel +00 32 92 28 10 97 mailto:itext-questions@lists.sourceforge.net