Page Event Methods:
If you generate a PDF file using high-level iText objects, you add structured content
to a Document-object.
This content is automatically being translated to PDF syntax by the
PdfWriter.
The hidden (package private) object PdfDocument-object
is responsible for drawing the content on different pages.
While this happens, the process adding content (your program) is not aware of all this PDF specific work.
You can ask the PdfWriter for the current page number
with PdfWriter.getPageNumber(),
but this is all very limited. If you really want to control what happens inside the writer,
you need to add a PdfPageEvent:
The methods onChapter, onSection, onChapterEnd and onSectionEnd do just the same, but the first two also pass the chapter or section title. This can be used to set the content of some header or footer (as in the 'Romeo and Juliet' example below), or to construct a Table-of-Contents.
Go to top of the page// class MyPageEvent implements the PdfPageEvent interface MyPageEvent event = new MyPageEvent(); writer.setPageEvent(event);The PdfPageEvent interface contains the following methods you have to implement in your own class MyPageEvent:
- public void onOpenDocument(PdfWriter writer, Document document);
- public void onCloseDocument(PdfWriter writer, Document document);
- public void onStartPage(PdfWriter writer, Document document);
- public void onEndPage(PdfWriter writer, Document document);
- public void onParagraph(PdfWriter writer, Document document, float paragraphPosition);
- public void onParagraphEnd(PdfWriter writer,Document document,float paragraphPosition);
- public void onChapter(PdfWriter writer,Document document,float paragraphPosition, Paragraph title);
- public void onChapterEnd(PdfWriter writer,Document document,float paragraphPosition);
- public void onSection(PdfWriter writer,Document document,float paragraphPosition, int depth, Paragraph title);
- public void onSectionEnd(PdfWriter writer,Document document,float paragraphPosition);
- public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text);
Open and close a document, start and end a page
The onOpenDocument method
and the first onStartPage method
are called just after the document is opened and after the first page has been initialized.
onOpenDocument is mostly used to initialize some parameters that you defined
yourself in your own page event implemantation.
onStartPage is called just after each new page has been initialized.
The onEndPage method is called just before a new page is started
and initialized. This is the best method to add some headers and footers.
I don't recomment to add headers and footers in the onStartPage method,
because this can lead to all kinds of quirky effect (for instance an extra, unwanted blank page at the end of your document).
The onCloseDocument
method is called just before all streams are closed. This is the ideal place to complete
the template containing the total number of pages, if you have some footer indicating
'page X of Y'. It is only just before closing the document that you know the exact value of Y.
In your implementation of these methods, you always get the instance of the writer that
triggered the event a Document-object. THIS IS NOT THE SAME
OBJECT as the one you are adding structured content to. This is an instance of the (hidden)
PdfDocument-object. You can only invoke a limited number of
methods on this object.Adding paragraphs, chapters, section
When a paragraph is added, you might want to know the current Y position on your page.
Below you'll find an example adding bookmarks automatically;
each entry in the outline tree points at the starting position of a paragraph.
This outline tree is generated in an onParagraph event.
If you need to add some object at an absolute place just after a paragraph, just use
the onParagraphEnd-method.The methods onChapter, onSection, onChapterEnd and onSectionEnd do just the same, but the first two also pass the chapter or section title. This can be used to set the content of some header or footer (as in the 'Romeo and Juliet' example below), or to construct a Table-of-Contents.
Generic tags
Generic tags are already discussed elsewhere, for instance when we added
generic functionality
to a Chunk object. In the 'Romeo and Juliet' example, we are going to use this method to count
the number of interventions of each character in the play.
Examples:
Headers/Footers
If you want to add a Header and/or a Footer to each page in your document,
you have to do this in an onEndPage event.
Example: java
com.lowagie.examples.directcontent.pageevents.EndPage
Headers and footers in an EndPage event: see endpage.pdf
Headers and footers in an EndPage event: see endpage.pdf
Page X of Y
In this example, not only we add a header and a footer.
We also use a template in the footer to display 'page X of Y'.
The total number of pages is added to the PdfTemplate in the
onCloseDocument event.
As you can see, watermarks can be added in onStartPage,
but you could also do this in onEndPage
(where we also draw a Rectangle around the text on each page).
Example: java
com.lowagie.examples.directcontent.pageevents.PageNumbersWatermark
Making a document with a header containing 'page x of y' and with a watermark on every page.: see pageNumbersWatermark.pdf
External resources for this example: logo.gif
Making a document with a header containing 'page x of y' and with a watermark on every page.: see pageNumbersWatermark.pdf
External resources for this example: logo.gif
Bookmarks
This example was already mentioned in the chapter on
bookmarks.
Example: java
com.lowagie.examples.directcontent.pageevents.Bookmarks
Using paragraph events: see bookmarks.pdf
Using paragraph events: see bookmarks.pdf
Romeo and Juliet: XML to PDF:
In this example, we combine some of the most interesting functionalities of iText.
We have an XML file (playRomeoJuliet.xml) containing the complete play 'Romeo and Juliet' by William Shakespeare.
We have defined a tagmap (tagmapRomeoJuliet.xml) that translates the tags in the XML to tags that can be understood by iText.
iText will parse the XML and generate the PDF file using this tagmap.
A Speaker-class was written to keep track of all the different speakers. As you can see in the page event implementation, we update the list of speakers in the onGenericTag method. We do some initialisations in the onOpenDocument method, we keep track of the current act in the onChapter method, we add this information as a header on every even page of the document and also put a 'page X of Y'-footer in the onPageEnd method and finally, we set the value of this Y in the onCloseDocument method. After the document is parsed, we retrieve the alphabetical list of speaker from out event class and add an extra page with this info.
Go to top of the pageA Speaker-class was written to keep track of all the different speakers. As you can see in the page event implementation, we update the list of speakers in the onGenericTag method. We do some initialisations in the onOpenDocument method, we keep track of the current act in the onChapter method, we add this information as a header on every even page of the document and also put a 'page X of Y'-footer in the onPageEnd method and finally, we set the value of this Y in the onCloseDocument method. After the document is parsed, we retrieve the alphabetical list of speaker from out event class and add an extra page with this info.
Example: java
com.lowagie.examples.directcontent.pageevents.Events
Using PageEvents: see RomeoJuliet.pdf
External resources for this example: tagmapRomeoJuliet.xml playRomeoJuliet.xml
Extra jars needed in your CLASSPATH: crimson.jar
Using PageEvents: see RomeoJuliet.pdf
External resources for this example: tagmapRomeoJuliet.xml playRomeoJuliet.xml
Extra jars needed in your CLASSPATH: crimson.jar