Showing posts with label Document. Show all posts
Showing posts with label Document. Show all posts

Saturday, June 26, 2010

iText - Opening a Document

Before manipulating a pdf document you have to "open" it first.

Document document = new Document();
document.open();

It is very important to do any changes to page size or margins etc. BEFORE opening the document. Otherwise, the defaults will be used for the first page and any alterations will only be effective from the second page onwards.

//Correct
Document document = new Document(PageSize.A5, 32 ,76 ,100, 200);
document.open();

//Wrong
Document document = new Document();
document.open();
document.setMargins(32, 76, 100, 200);

The reason for this is many document types keep meta data including page setup and version information in the file header which is created before the document itself.

The meta data of a PDF document can be set by using the accessor methods within the Document class. This includes:

  • addTitle("Title")
  • addSubject("Subject")
  • addKeywords("Metadata, iText")
  • addCreator("Lilpinkthings Program")
  • addAuthor("Lilpinkthing")
  • addHeader("ValidFrom, 0")

Don't change the producer and creation date meta values. They will tell you what version of iText was used to create the file if support is needed later on. These values must be set before opening the document.

It is possible also possible to tell a PdfWriter which pdf version to use - the default is 1.4.

Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("Output.pdf");
writer.setPdfVersion(PdfWriter.VERSION_1_6);
document.open();

Again this MUST be called before opening the document, because it goes into the header file.

This gives us 6 basic steps of PDF creation which look like this:
  1. Create a Document
  2. Create a PdfWriter and associate the Document and an OutputStream with it
  3. Set all meta data, version and page setup information
  4. Open the Document
  5. Add content
  6. Close the document
Code Example:
Document document = new Document(); //step 1
PdfWriter.getInstance(document, new FileOutputStream("Output.pdf") ); //step 2
document.addKeywords("hello, world, pdf, iText"); //step 3
document.addAuthor("lilpinkthing"); //step 3
document.open(); //step 4
document.add(new Paragraph("Hello there")); //step 5
document.close(); //step 6

The document.close() line here is VERY important. If you forget to add this you will probably get some crazy error similar to "There was an error opening this document. The file is damaged and could not be repaired." Don't panic, just close the document.

In-depth iText information can be found in Bruno Lowagie's excellent book iText In Action http://www.manning.com/lowagie2/




iText - Choosing a Writer

Allegedly there are several classes derived from the abstract DocWriter class which can be used for different kinds of output files - pdf, rtf and html. However, using iText 5.0.2 it seems that both the .rft and the .html options have been removed. So let's focus on pdf creation for now.

You can either write a document to file, memory or the output stream (e.g. stdout).

Document document = new Document();

// write to file
PdfWriter.getInstance(document, new FileOutputStream("Output.pdf");

//write to memory
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PdfWriter.getInstance(document, buffer);

//write to System.out
PdfWriter.getInstance(document, System.out);

Note that when using the file output or System.out the document is outputted directly but with the ByteArrayOutputStream it is buffered for use at a later date. To retrieve it, the reader needs to be passed the ByteArrayOutputStream cast as a ByteArray.

//read from memory
PdfReader reader = new PdfReader(buffer.toByteArray());

This is extremely useful when you need to do multiple passes on a pdf document. For example, you may want to read in multiple pdfs and write page numbers for the new combined document on each page. The pdfs can be read in, merged together and stored in memory then the whole new document can be manipulated and annotated. This saves writing an intermediary file to disk.

In-depth iText information can be found in Bruno Lowagie's excellent book iText In Action http://www.manning.com/lowagie2/

iText - Page Setup

First things first. There are 72 points to 1 inch. This means that a document with a page size of 216pt x 720pt is actually 3 inches wide and 10 inches in height.

The lower-left corner of the page is used as the origin of the coordinate system when manipulating margins, rectangles etc.

Page sizes for documents can be defined using the Rectangle class.

Rectangle pagesize = new Rectangle(216f, 720f);
Document document = new Document(pagesize);

When using a Rectangle for page size, it allows the background color of the pages to be specified.

pagesize.setBackgroundColor(new BaseColor(0x64, 0x95, 0xed); //using rectangle from before

Be careful here. The signature for setBackgroundColor expects a BaseColor, from com.itextpdf.text.BaseColor not a Color from java.awt.Color.

Page sizes can also be set by specifying one of the static constants using the PageSize class.

Document document = new Document(PageSize.LETTER);

In addition, the pagesize object can be used to make the pages landscape.

PageSize.Letter.rotate(); or
Document document = new Document(pagesize.rotate()); //using the rectangle from before

PageSize can also be used to define the margins of the page. The margins are left, right, top and bottom respectively in the signature.

PageSize.A5, 36, 72, 108, 180) // 36 left, 72 right, 108 top, 180 bottom

Margin mirroring can be called on the document to mirror the margins on odd and even pages.

Document document = new Document(PageSize.A5, 36, 72, 108, 180) ;
document.setMarginMirroring(true);


In-depth iText information can be found in Bruno Lowagie's excellent book iText In Action http://www.manning.com/lowagie2/