iText Class Library

Transcription

iText Class Library
iText Class Library
Fachhochschule Nordwestschweiz FHA
University of Applied Sciences Aargau
Autor:
Filipe Luis
[email protected]
Studiengang:
Fach:
Informatik
Seminar Enterprise Computing
Reporting in Java Web Applications
Prof. Dr. Dominik Gruntz
07. Mai 2004
Dozent
Datum:
2
Abstract
iText ist eine offene und frei erhältliche Java-Bibliothek zur Erzeugung von PDF Dokumenten. Mit dieser Bibliothek können PDFs auch aus Web-Applikationen programmatisch erzeugt werden. Dieser Seminarbericht soll einen Überblick über die Library
geben und dadurch die Möglichkeiten von iText aufzeigen. Im Besonderen sollen dabei die Möglichkeiten der PDF-Erzeugung mittels XML Dokumenten und aus Servlets
aufgezeigt werden.
Filipe Luis
Fachhochschule Aargau
Inhaltsverzeichnis
3
Inhaltsverzeichnis
1. Was ist iText
4
2. Einführung: Einfache Dokumente
2.1. Das erste Dokument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
5
3. Elemente eines Dokuments
3.1. Chunks . . . . . . . . . .
3.2. Phrase . . . . . . . . . .
3.3. Paragraphs . . . . . . .
3.4. Sprungmarken . . . . . .
3.5. Listen . . . . . . . . . .
3.6. Tabellen . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
8
9
9
9
9
10
4. Positionierung & Writer
4.1. Automatische Anordnung
4.2. PdfWriter . . . . . . . . .
4.2.1. Interne Schichten .
4.2.2. Externe Schichten .
4.3. HtmlWriter . . . . . . . .
4.4. XmlWriter . . . . . . . . .
4.5. RtfWriter . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
12
13
13
14
15
16
5. iText in Web-Applikationen
5.1. Servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
17
6. iText & XML
6.1. Tagmap für eigene XML Dokumente . . . . . . . . . . . . . . . . . . . . . . . . .
20
20
A. Source Code
A.1. PdfCotnentByte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2. Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.3. Servlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
22
23
24
Filipe Luis
Fachhochschule Aargau
4
1. Was ist iText
iText ist eine Bibliothek zur dynamischen Erzeugung und Manipulation von Portable Document
Format (PDF) Dateien. Das Projekt wird von Bruno Lowagie vorangetrieben und entwickelt. Die
iText Bibliothek bietet dem Entwickler umfangreiche Möglichkeiten in Java PDF Dokumente zu
erstellen. Seit kurzer Zeit wurde iText auch auf die C# Plattform portiert (einige Klassen stehen
allerdings noch nicht zur Verfügung, weiterführende Informationen dazu unter [4]).
Die iText Bibliothek umfasst im wesentlichen folgende Features:
• Unterschiedliche Seitengrössen (Beispiele: A0 bis A10, Legal, Letter uvm.
• Hoch- oder Querformat
• Seitenabstände
• Tabellen
• Silbentrennung
• Kopf- und Fusszeilen
• Seitennummerierung
• Barcodes
• Schrifttypen
• Dokument Verschlüsselung
• Integration von Bilddateien (Formate: JPEG, GIF, PNG und WMF)
• Geordnete und ungeordnete Listen
• Dokumenttemplates
• Erzeugung von PDF Dateien mittels XML
Die gesamte Bibliothek ist unter [3] erhältlich und offen.
Filipe Luis
Fachhochschule Aargau
5
2. Einführung: Einfache Dokumente
Ziel der Einführung ist es, die notwendigen Schritte zur Erzeugung einer PDF Datei aufzuzeigen
und zu erläutern.
2.1. Das erste Dokument
Die Erstellung eines PDF Dokuments mit der iText Bibliothek gliedert sich in fünf Schritte:
1. Erzeugung einer Document Instanz.
2. Erzeugung eines Writers, welcher als Obeserver des Document Objekts agiert und zugefügten
Inhalt in die PDF Datei schreibt (siehe Kapitel 4.1 auf Seite 11).
3. Das Dokument muss, um Inhalt hinzufügen zu können explizit geöffnet werden.
4. Hinzufügen des Inhaltes.
5. Schliessen des Dokumentes (damit die OutputStreams geleert werden).
Nachfolgend wurde der Programm-Code zur Erzeugung eines einfachen PDF Dokumentes aufgelistet. Im Code finden sich die oben beschriebenen Schritte wieder!
Listing HelloWorld.java:
import
import
import
import
java . i o . FileOutputStream ;
j a v a . i o . IOException ;
com . l o w a g i e . t e x t . ∗ ;
com . l o w a g i e . t e x t . p d f . PdfWrite r ;
public c l a s s HelloWorld
{
public s t a t i c void main ( S t r i n g [ ] a r g s )
{
// − − 1. S c h r i t t : Document I n s t a n z
Document doc = new Document ( ) ;
try
{
// − − 2. S c h r i t t : Writer e r z e u g e n
PdfWrite r . g e t I n s t a n c e ( doc , new F i l e O u t p u t S t r e a m ( ” HelloWorld . p d f ” ) ) ;
// − − 3. S c h r i t t : Dokumentö f f n e n
doc . open ( ) ;
Filipe Luis
Fachhochschule Aargau
2.1. Das erste Dokument
6
// − − 4. S c h r i t t : I n h a l t ü h i n z u f g e n
Font f o n t = FontFactory . g e t F o n t ( FontFactory . HELVETICA BOLD, 3 4 ) ;
Chunk c = new Chunk ( ” H e l l o World” , f o n t ) ;
doc . add ( c ) ;
// − − 5. S c h r i t t : Dokument s c h l i e s s e n
doc . c l o s e ( ) ;
System . out . p r i n t l n ( ” HelloWorld . p d f c r e a t e d ! ” ) ;
}
catch ( DocumentException e )
{
e . printStackTrace ( ) ;
}
catch ( IOException e )
{
e . printStackTrace ( ) ;
}
}
}
Die erzeugte HelloWorld.pdf Datei:
Abbildung 2.1.: Output des ersten Beispiels.
Seitengrösse. Das Objekt com.lowagie.text.Document besitzt mehrere Konstruktoren. Bei
der Erzeugung einer Document Instanz wird ein Rectangle Objekt erwartet (Vorsicht: Ein com.lowagie.text.Rectangle und nicht ein java.awt.Rectangle Objekt), wird kein Parameter angegeben, so wird das statische Rectangle Objekt PageSize.A4 verwendet (default).
Metadata. Über diverse Document Methoden können dem PDF Dokument Metadaten hinzugefügt werden. Folgende stehen zur Verfügung:
public boolean addTitle(String title)
public boolean addSubject(String subject)
Filipe Luis
Fachhochschule Aargau
2.1. Das erste Dokument
7
public boolean addKeywords(String keywords)
public boolean addAuthor(String author)
public boolean addCreator(String creator)
Der Rückgabetyp boolean ist true wenn die entsprechende Operation erfolgreich ausgeführt werden konnte, sonst false.
Verschlüsselung. Der PdfWriter kann mit der Methode
public void setEncryption(byte[] userPassword, byte[] ownerPassword,
int permissions, boolean strength128Bits) angewiesen werden, das Dokument zu verschlüsseln. Mit Ausnahme der Passwörter können alle Parameter mit den statischen Felder der Klasse
PdfWriter angegeben werden. Unter anderem steht dem Entwickler das Feld PdfWriter.AllowPrinting zur Verfügung. Wird dieser Wert nicht angegeben, so kann der User ohne Angabe des korrekten Passworts, die PDF Datei nicht mehr drucken (zumindest nicht ohne gewisse Bemühungen).
Einheiten. In der iText Bibliothek wird die typographische Einheit Punkt verwendet. 72 Punkte
ergeben ein Inch oder ∼ 0.4cm. Eine A4 Seite hat somit 595 Punkte in der Breite und 842 Punkte
in der Höhe.
Filipe Luis
Fachhochschule Aargau
8
3. Elemente eines Dokuments
Um einen Eindruck zu vermitteln was in iText dargestellt werden kann, sollen einige elementare
Bausteine erläutert werden. Diese Liste ist bei weitem nicht vollständig, sie soll lediglich eine
Übersicht vermitteln.
3.1. Chunks
Die ‘kleinste’ Einheit in iText ist das Chunk Objekt. Dieses Element besteht nur aus einem String
mit einer bestimmten Schrift. Die weiteren Elemente Phrase und Paragraph bestehen aus lauter
aneinander gehängten Chunk Objekten. Ein Beispiel für ein Chunk Objekt ist im Listing 2.1 auf
Seite 5 zu sehen.
Formatierung eines Chunks. Verschiedene Möglichkeiten stehen dem Entwickler zur Verfügung
um einen Chunk zu formatieren.
• Für ein Chunk Text der ‘Unterstrichen’ und ‘Kursiv’ gesetzt werden soll, genügt folgende
Anweisung:
Chunk chunk = new Chunk("Kursiv und unterschrichen",
FontFactory.getFont(FontFactory.HELVETICA,12, Font.UNDERLINE | Font.ITALIC));
Weitere Möglichkeiten wie z.B. Durchstreichen des Texts sind vorhanden.
• Mit der Methode setTextRise(float f) kann in Punkten definiert werden, ob der Text
Hochgestellt oder Tiefgestellt gedruckt werden soll. Die Angabe erfolgt relativ zur Baseline,
wobei ein positives Vorzeichen den Text nach oben verschiebt, ein negatives den Text nach
unten versetzt.
• Die Hintergrundfarbe kann mit der Methode setBackground(java.awt.Color color) gesetzt werden.
Filipe Luis
Fachhochschule Aargau
3.2. Phrase
9
3.2. Phrase
Das Phrase Objekt stellt eine Sammlung von einem oder mehreren Chunk Objekten dar. Zusätzlich
definiert das Phrase Objekt ein sog. leading (Zeilenabstand) und eine Main Font welche für
alle beinhalteten Chunk Elemente gilt (es ist möglich einzelnen Elementen ein anderes Layout
zuzuweisen).
3.3. Paragraphs
Ein Absatz besteht aus einem oder mehreren Chunk und/oder Phrase Objekten. Ein Paragraph
Objekt kann wie ein Phrase Objekt formatiert werden. Zusätzlich stehen jedoch noch die Möglichkeiten den Text einzurücken und auszurichten (links, rechts oder zentriert) zur Verfügung.
3.4. Sprungmarken
iText bietet die Möglichkeit, ähnlich wie in HTML, Links zu definieren. Als Sprungziele können
interne (innerhalb des Dokumentes) sowie auch externe Quellen referenziert werden (z.B. eine
Website). Nachfolgend ist ein Anchor Objekt dargestellt, welches auf die Website der Fachhochschule Aargau verweist, und ein Anchor-Paar, welches eine Sprung- und eine Zielmarke darstellt.
Das Konzept der Anchors entspricht demjenigen der Links in HTML. Der Entwickler definiert
also ein String, im nachfolgenden Beispiel jeweils goto, welches beim Anklicken den Betrachter
des Dokuments zur Zielmarke springen lässt. Die Zielmarke besteht ebenfalls aus einem String das
für den Benutzer sichtbar ist (hier: destination) und einem Namen (NextPage) welches intern
als Markierung des Sprungsziels dient, für den Betrachter jedoch unsichtbar ist.
Anchor xref = new Anchor("goto");
xref.setReference("http://www.fh-aargau.ch/");
xref.setName("Website");
Anchor iref = new Anchor("goto", afont);
iref.setReference("#NextPage");
//-- extern
//-- intern
Anchor zref = new Anchor("destination");
zref.setName("NextPage");
3.5. Listen
Mit dem List Objekt ist es möglich Listen zu erstellen. Der Kunstruktor erwartet ein boolean
Flag, mit welchem angezeigt wird, ob die Liste geordnet oder ungeordnet ist. Verschachtelte Listen
Filipe Luis
Fachhochschule Aargau
3.6. Tabellen
10
sind ebenfalls möglich. Im Anhang A.2 auf Seite 23 ist ein Beispiel zu finden.
3.6. Tabellen
Mit der Table Klasse können Tabellen erzeugt werden. Die Klasse stellt zwei Konstruktoren zur
Verfügung:
• Table(int spalten)
• Table(int spalten, int zeilen)
Mit folgenden Parametern kann das Aussehen der Tabelle formatiert werden:
Cellspacing und Cellpadding: Mit der Methode setSpacing(float value) kann der Abstand
vom Zelleninhalt und dem Zellenrand in Punkte angegeben werden. Um den Abstand der Zellen zum Tabellenrand (Cellpadding) zu definieren, wird die Methode setPadding(float value)
aufgerufen.
Alignment: Um den Inhalt in den Zellen auszurichten können folgende Methoden verwendet
werden.
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
Color: Die Hintergrundfarbe wird mit der Methode setBackgroundColor(Color color) gesetzt.
Um der Tabelle Inhalt zuzufügen, werden Instanzen der Cell Klasse verwendet. Die Cell Objekte
können ein beliebiges Element aufnehmen. Nachdem der Inhalt einer Zelle bestimmt ist, kann
die Zelle über die Methode addCell(...) der Tabelle eingefügt werden. Die Zellen werden von
links nach rechts eingefügt. Beim Konstruktor kann die Zeilenanzahl weggelassen werden, da die
Tabelle automatisch Zeilen einfügt wenn mehr benötigt werden sollten (dies gilt auch für den
zweiten Konstruktor, obwohl die Zeilenanzahl angegeben werden kann).
Informationen zum Umbruch der Tabellen bei einem Seitewechsel sind im Abschnitt 4.1 auf Seite 12
zu finden.
Filipe Luis
Fachhochschule Aargau
11
4. Positionierung & Writer
Die iText Bibliothek definiert fünf Writer: DocWriter, PdfWriter, HtmlWriter, XmlWriter und
RtfWriter. Die Writer werden wie bereits im ersten Beispiel 2.1 auf Seite 5 gesehen im zweiten
Schritt erzeugt. Sie agieren als Listener und werden über die add() Methoden über Änderungen
am Dokument notifiziert. Jedes Element muss also über die add(...) Methode der Document
Klasse hinzugefügt werden, da die Writer ansonsten nicht über die Änderung notifiziert werden.
Die Writer entscheiden dann, je nach eingefügtem Element, wie sie ihn darstellen. Die Writer
sind dabei auch an die Grenzen des jeweiligen Datenformats gebunden. Nicht alles was in PDF
Dokumenten darstellbar ist, kann beispielsweise auch in HTML umgesetzt werden (z.B. newPage()
). Der Writer ‘kennt’ also die Möglichkeiten des Formats und versucht diese entsprechend zu
nutzen.
Abbildung 4.1.: Die iText Writers.
4.1. Automatische Anordnung
Die Writer sind auch für die Anordnung der Elemente zuständig, d.h. der Programmierer definiert
nur die Struktur des Dokumentes (vergleichbar wie beim schreiben von HTML Seiten). Beim
Entwickeln definiert der Programmierer ein Element nach dem anderen und fügt diesen dem
Dokument mit der add(...) Methode hinzu. Die Writer werden von der Document Klasse über
diese Änderung notifiziert. Der Writer nimmt diese Elemente entgegen und positioniert diese.
Bei der Positionierung hängt die Anordnung u.a. vom Typ des Elementes ab: Chunk und Phrase
Objekte werden beispielsweise nacheinander auf der gleichen Zeile von links nach rechts eingefügt
Filipe Luis
Fachhochschule Aargau
4.2. PdfWriter
12
(Die Zeilenumbrüche werden dabei von iText selbst gesteuert). Die Paragraph Objekte haben ein
leading Parameter was heisst, dass die Absätze immer auf einer neuen Zeile beginnen.
Der Entwickler kann mit gewissen Methoden auf die automatische Positionierung Einfluss nehmen
(dies hängt allerdings auch vom Format ab, wie bereits erwähnt sind nicht alle Writer in der Lage
alle Elemente korrekt darzustellen). Beispiele:
• newPage() Methode der Document Klasse: Erwingt in jedem Falle einen Seitenumbruch.
• Mit dem leading Parameter im Paragraph Konstruktor (Abstand zur vorangehende Zeile).
• Mit der Methode setKeepTogether() der Paragraph Klasse, wird iText einen Absatz nicht
durch einen Seitenumbruch trennen. In diesem Falle wird der ganze Absatz auf die nächste
Seite verschoben.
Seitenumbrüche & Tabellen. iText bestimmt die Seitenumbrüche automatisch. Dabei werden
auch Tabellen problemlos umgebrochen. Es besteht sogar die Möglichkeit den Header der Tabelle
auf jeder Seite zu wiederholen.
Der Entwickler kann auf die Art wie die Tabelle umgebrochen wird mit folgenden zwei Methoden
Einfluss nehmen:
• setTableFitsPage(true): Die Tabelle wird, wenn möglich, auf eine Seite gesetzt. Dabei wird versucht, die Tabelle auf der aktuellen Seite unterzubringen, ansonsten wird mit
newPage() die Tabelle auf die nächste Seite gesetzt. Falls diese Versuche scheitern, weil der
Umfang zu gross für eine Seite ist, wird sie dennoch umgebrochen.
• hasToFitPageCells(true): Die Tabelle wird so umgebrochen, dass ganze Zeilen umgebrochen werden. Ist diese Option nicht gesetzt, so kann es geschehen, dass ein Seitenumbruch
innerhalb einer Zeile stattfindet.
Daten Stream. Während dem Anordnen der Elemente erzeugen die Writers fortlaufend einen
Daten Stream (darum sollte das Dokument auch immer explizit mit close() geschlossen werden,
damit die Buffer geleert werden). Dies stellt vor allem bei der Erzeugung von dynamischen Inhalt
(Inhaltsverzeichnisse, Referenzen usf.) eine Problematik dar und setzt der iText Bibliothek auch
gewisse Grenzen.
4.2. PdfWriter
Der PdfWriter unterscheidet sich in einer Eigenschaft von den anderen Writern: Der Entwickler
besitzt die Möglichkeit, Elemente auch manuell an absolute Positionen zu setzten. Dazu wurde in
der iText Library ein Modell mit vier hierarchischen Layers eingeführt. Die Hierarchie besteht aus
vier PdfContentByte Objekten, welche je eine Schicht repräsentieren.
Filipe Luis
Fachhochschule Aargau
4.2. PdfWriter
13
Externer Layer oberhalb von Text und Grafik
PdfContentByte cb = writer.getDirectContent()
Interner Layer für Text
Interner Layer für Grafik
Externer Layer unterhalb von Text und Grafik
PdfContentByte cb = writer.getDirectContentUnder()
4.2.1. Interne Schichten
Zwei dieser vier Layers werden vom PdfWriter intern für die automatische Positionierung verwendet, auf diese hat der Programmierer keinen direkten Zugriff.
Die Unterteilung der Layers in Text- und Grafik-Schichten dient u.a. der Darstellung von Tabellen:
Die Ränder und Hintergrundfarben der Zellen werden im Grafik Layer gesetzt, der eigentliche
Inhalt der Zellen wird im Text-Layer abgelegt.
Alle Elemente, welche über die Methode add( Element element ) der Document Klasse dem
Dokument hinzugefügt werden, werden über diese interne PdfContentByte Objekte gesetzt.
4.2.2. Externe Schichten
Um auf die externen Schichten Zugriff zu erhalten, kann der Entwickler die Methoden
getDirectContent() und getDirectContentUnder() der PdfWriter Klasse verwenden. Alle
Schichten arbeiten völlig unabhängig voneinander, d.h. die Textfragmente können sich überlappen! Wird der Text in der obersten Schicht eingefügt, so überlappt er die restlichen Elemente,
wird er in der untersten Schicht eingefügt so verschwindet er hinter den oberen Elementen.
Absolute Positionierung von Text
Nachfolgend wird ein Beispiel aufgezeigt wie man einen Text absolut positioniert. Beim Positionieren ist besonders der Ursprung des Koordinatensystems zu erwähnen, dieser befindet sich in
der linken unteren Ecke.
PdfContentByte cb = writer.getDirectContent();
BaseFont bf = BaseFont.createFont(
BaseFont.HELVETICA,
BaseFont.CP1252,
BaseFont.NOT_EMBEDDED);
cb.beginText();
cb.setFontAndSize(bf, 14);
cb.setTextMatrix(0, 0);
Filipe Luis
Fachhochschule Aargau
4.3. HtmlWriter
14
cb.showText("Urspung Koodrinatensystem (0,0).");
cb.endText();
Bemerkungen. Zusammengefasst müssen folgende Schritte beachtet werden:
1. Instanz eins PdfContentByte Objektes erzeugen.
2. Erzeugen einer BaseFont.
3. Den Text-Bereich mit Aufruf der Methode beginText() eröffnen.
4. Die Schrift und die Grösse setzen.
5. Eine Text-Matrix an einer bestimmten Stelle öffnen.
6. Mit der Methode showText(...) den Text einfügen.
7. Den Text-Bereich durch Aufruf von endText() schliessen.
Ein ausführliches Beispiel, in welchem u.a. auch Text unter bestehende Elemente gelegt wird ist
im Anhang A.1 auf Seite 22 zu finden.
Rotationen. Die iText Library bietet noch eine weitere Methode Text zu setzen an. Diese Methode setTextMatrix(float a, float b, float c, float d, float x, float y) erhält als
Parameter die Koeffizienten einer Rotationsmatrix. Auch hierzu findet man im erwähnten Beispiel
PdfContentByte im Anhang eine Anwendung.
4.3. HtmlWriter
Der HtmlWriter arbeitet im wesentlichen gleich wie der PdfWriter. Bruno Lowagie empfiehlt
den professionellen Einsatz dieses Packages nicht, da der HTML Code nicht sehr ‘schön’ ist aber
vor allem noch nicht alle Features unterstützt werden. Für das Debugging von PDF Dokumenten
hingegen, wird dieses Paket sehr empfohlen, da der HTML Quellcode wesentlich einfacher zu
verstehen ist.
Das Einbinden des HtmlWriters ist relativ einfach:
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("beispiel.pdf"));
HtmlWriter.getInstance(document, new FileOutputStream("beispiel.html"));
Filipe Luis
Fachhochschule Aargau
4.4. XmlWriter
15
Dadurch wird nun bei jedem add( Element element ) Aufruf gleich auch HTML Code erzeugt.
Wenn man dem ersten Beispiel 2.1 auf Seite 5 noch einen HtmlWriter hinzufügen würde, erhält
man folgenden HTML Code:
<html>
<head>
<!-- Producer: iTextXML by lowagie.com -->
<!-- CreationDate: Thu Apr 22 17:00:50 CEST 2004 -->
</head>
<body leftmargin="36.0" rightmargin="36.0" topmargin="36.0" bottommargin="36.0">
<span>Hello World</span>
</body>
</html>
Weiterführende Informationen sind in der API Dokumentation unter [2, com.lowagie.text.html] zu
finden.
4.4. XmlWriter
Der XmlWriter wird im Kapitel 6 auf Seite 20 eingehender betrachtet und hier nur der Vollständigkeit halber erwähnt.
Das Einbinden des XmlWriters erfolgt analog zur Einbindung des HtmlWriters. Zur Erzeugung
des XML Dokuments wird die Document Type Declaration von iText
(http://itext.sourceforge.net/itext.dtd) verwendet. Im wesentlichen stellt die DTD eine
Abbildung der iText Elemente dar. So kann jedes Element wie z.B. ein Chunk Objekt in XML
dargestellt werden.
Wenn man dem ersten Beispiel 2.1 auf Seite 5 noch einen XmlWriter hinzufügen würde, erhält
man folgenden XML Code:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE ITEXT SYSTEM "http://itext.sourceforge.net/itext.dtd">
<itext creationdate="Thu Apr 22 17:16:57 CEST 2004" producer="iTextXML by lowagie.com">
<chunk font="Helvetica" size="34.0">Hello World</chunk>
</itext>
Filipe Luis
Fachhochschule Aargau
4.5. RtfWriter
16
4.5. RtfWriter
Mit der iText Library kommt ebenfalls noch ein RtfWriter mit. Das Einbinden verläuft gleich
wie bei den vorangehenden Writer.
Bemerkungen. Einige Features werden im RTF Format noch nicht unterstützt: z.B. Phrasen
mit einem Leading, verschachtelte Tabellen und das Rotieren von Bildern.
Filipe Luis
Fachhochschule Aargau
17
5. iText in Web-Applikationen
Um Dokumente aus einem Servlet heraus zu erstellen, gibt es zwei verschiedene Ansätze:
1. Das PDF Dokument wird auf dem Server erzeugt und gespeichert. Die Applikation verwendet
ein java.io.FileOutputStream Objekt um das Dokument auf dem Filesystem abzulegen.
In einem nächsten Schritt kann der Webuser das Dokument über das Hypertext Transfer
Protocol (HTTP) anfordern (GET).
2. Das PDF Dokument wird auf dem Server erzeugt aber nicht gespeichert. Über die Angabe
des Content Types (Type: Application, Subtype: pdf) kann dem Client direkt ein PDF
Dokument über das HTTP Protokoll verschickt werden.
Im Rahmen dieses Semniarberichtes wird nur auf die zweite Variante eingegangen, da sie gegenüber
der ersten gleich mehrere Vorteile bietet:
Für die erste Variante muss auf dem Server eine Datei gespeichert und dies macht eigentlich nur
dann Sinn, wenn sie nach der Erzeugung für längere Zeit zur Verfügung stehen muss. Damit der
Client auf das abgespeicherte Dokument zugreifen kann, muss ihm ein Link angegeben werden.
Zusätzlich entsteht die Problematik des Wegräumens: das abgespeicherte Dokument muss wieder
entfernt werden. All diese Probleme können mit der zweiten Variante vermieden werden.
5.1. Servlet
Bevor irgend welche Daten an den Client zurückgeschickt werden, müssen die HTTP Response
Headers gesetzt werden. In diesem Fall unterscheidet sich vor allem der Content-Type von den
‘herkömmlichen’ Servlets.
Content-type Falls der Content-type nicht gesetzt wird, muss der Client selber herausfinden
wie er das File handhaben will. Mit den Content-types kann das Format festgelegt werden. In
diesem Fall wird der Content-type wie folgt gesetzt:
response.setContentType("application/pdf");.
Content-disposition Mit dieser Angabe kann dem Client der Filename des Dokuments mitgeteilt werden. Zusätzlich kann der Client angewiesen werden, das Dokument im Browser anzuzeigen
Filipe Luis
Fachhochschule Aargau
5.1. Servlet
18
oder aber eine externe Applikation zu verwenden. Hier:
response.setHeader("Content-disposition", "inline; filename=response.pdf");
Content-length Die Grösse des Dokumentes muss in Bytes angegeben werden. Dieser Parameter
muss stimmen, da der Browser sonst das Dokument nicht darstellen kann.
Beispiel ITextServlet. Nachfolgend soll ein Beispiel eines Servlets besprochen werden. Den gesamten Code findet man im Anhang A.3 auf Seite 24. Dieses Beispiel greift auf eine PostgreSQL
Datenbank zu. Die Verbindung zur Datenbank wird in der init(...) Methode aufgebaut, dieses
Thema wird jedoch an dieser Stelle nicht ausführlicher besprochen (weitere Informationen dazu
findet man auf den Webseiten [6] und [5]).
In der doGet(...) Methode des Servlets wird ein ByteArrayOutputStream deklariert, dieser
soll den Daten Stream, welcher vom PdfWriter erzeugt wird, entgegennehmen. Die Methode
createPDFByteArrayStream() führt dann die entsprechenden Queries auf der Datenbank aus,
um einige Daten für das PDF Dokument zu erhalten. Im weiteren wird in den bereits bekannten fünf Schritten ein PDF Dokument erzeugt. Dabei wird dieses mal nicht wie bisher in ein
FileOutputStream geschrieben (es soll ja keine Datei erzeugt werden). Statt dessen lääst man
den PdfWriter in ein ByteArrayOutputStream schreiben.
Document doc = new Document();
ByteArrayOutputStream pdf_data;
PdfWriter.getInstance(doc, pdf_data);
Mit den Daten aus der Datenbank wird eine Tabelle zeilenweise erzeugt. Nachdem der Inhalt
eingefügt wurde, wird mit doc.close() sichergestellt, dass der PdfWriter seine Daten vollständig
im ByteArrayOutputStream abgelegt hat. Dieser wird nun an die doGet(...) Methode zurück
gegeben.
Die doGet(...) Methode definiert die HTTP Response Headers. Der erzeugte PDF Daten Stream
wird danach wie folgt an den Client versendet.
ServletOutputStream sos;
sos = response.getOutputStream();
bstream.writeTo(sos);
sos.flush();
Filipe Luis
Fachhochschule Aargau
5.1. Servlet
19
Der Client erhält somit das PDF Dokument und wie in den HTTP Headers angegeben, wird das
Dokument inline geöffnet:
Abbildung 5.1.: Ein durch ein Servlet erzeugtes PDF Dokument.
Weiterführende Informationen zur dynamischen Erstellung von PDFs aus Web Applikationen sind
auf der Website [1] zu finden.
Filipe Luis
Fachhochschule Aargau
20
6. iText & XML
Die iText Library liefert im Paket com.lowagie.text.xml diverse Klassen für die Erzeugung
von PDF und RTF Dokumenten mit. Die Idee dabei ist recht einfach: Die Java Objekte wie
zum Beispiel Paragraph, List oder Chunk sollen in XML abgebildet werden. Diese Abbildung der
Elemente ist in der DTD http://itext.sourceforge.net/itext.dtd zu finden. Aus jedem XML
Dokument welches diese itext.dtd referenziert, ist somit direkt ein PDF Dokument erzeugbar.
6.1. Tagmap für eigene XML Dokumente
In der Regel möchte ein Entwickler jedoch ein spezifisches XML Dokument verwenden, welches
eine eigene DTD referenziert. In diesem Fall muss der Programmierer eine Tagmap schreiben,
welche die eigenen DTD Elemente in die itext DTD Elemente abbildet. Die Tagmap muss dem
Parser angegeben werden (tagmap.xml).
PdfWriter.getInstance(doc, new FileOutputStream("XML_doc.pdf"));
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse("XML_Document.xml", new SAXmyHandler(doc, new TagMap("tagmap.xml")));
Für ein Zeitungsartikel wurde folgende DTD geschrieben (itext_newspaper.dtd):
< !ELEMENT NEWSPAPER ( ARTICLE+)>
< !ELEMENT ARTICLE (AUTHOR, HEADLINE, BYLINE , BODY, NOTES)>
< !ELEMENT HEADLINE (#PCDATA)>
< !ELEMENT BYLINE (#PCDATA)>
< !ELEMENT BODY (#PCDATA)>
< !ELEMENT NOTES ( LINES ) ∗>
< !ELEMENT LINES (#PCDATA)>
< !ELEMENT AUTHOR (#PCDATA)>
< !ATTLIST ARTICLE
EDITOR CDATA #IMPLIED
DATE CDATA #IMPLIED
EDITION CDATA #IMPLIED
>
Ein XML Dokument (XML_Document.xml) welches diese DTD referenziert:
ı̈¿
<?xml version=” 1 . 0 ” e n c o d i n g=”UTF−8” ?>
< !DOCTYPE NEWSPAPER SYSTEM ” i t e x t n e w s p a p e r . dtd ”>
<NEWSPAPER>
<ARTICLE>
Filipe Luis
Fachhochschule Aargau
6.1. Tagmap für eigene XML Dokumente
21
<AUTHOR> F i l i p e L u i s</AUTHOR>
<HEADLINE> S c h l a g z e i l e</HEADLINE>
<BYLINE> U n t e r t i t e l</BYLINE>
<BODY>H i e r f o l g t d e r A r t i k e l . . . </BODY>
<NOTES>
<LINES>N o t i z 1</LINES>
<LINES>N o t i z 2</LINES>
</NOTES>
</ARTICLE>
</NEWSPAPER>
Und die Faltung der itext_newspaper.dtd auf die itext Elemente in der Tagmap:
<tagmap>
<t a g name=” i t e x t ” a l i a s=”NEWSPAPER” />
<t a g name=” n e w l i n e ” a l i a s=”ARTICLE” />
<t a g name=” p a r a g r a p h ” a l i a s=”AUTHOR” c o n t e n t=” Ã 41 K r z e l A u t o r : ”>
<a t t r i b u t e name=” s i z e ” v a l u e=” 12 ” />
<a t t r i b u t e name=” a l i g n ” v a l u e=” L e f t ” />
</ t a g>
<t a g name=” p a r a g r a p h ” a l i a s=”HEADLINE”>
<a t t r i b u t e name=” l e a d i n g ” v a l u e=” 36 ” />
<a t t r i b u t e name=” s i z e ” v a l u e=” 18 ” />
<a t t r i b u t e name=” a l i g n ” v a l u e=” Ce n te r ” />
</ t a g>
<t a g name=” p a r a g r a p h ” a l i a s=”BYLINE”>
<a t t r i b u t e name=” l e a d i n g ” v a l u e=” 20 ” />
<a t t r i b u t e name=” s i z e ” v a l u e=” 14 ” />
<a t t r i b u t e name=” a l i g n ” v a l u e=” Ce n te r ” />
<a t t r i b u t e name=” s t y l e ” v a l u e=” i t a l i c ” />
</ t a g>
<t a g name=” p a r a g r a p h ” a l i a s=”BODY”>
<a t t r i b u t e name=” l e a d i n g ” v a l u e=” 18 ” />
<a t t r i b u t e name=” s i z e ” v a l u e=” 12 ” />
<a t t r i b u t e name=” a l i g n ” v a l u e=” L e f t ” />
</ t a g>
<t a g name=” l i s t ” a l i a s=”NOTES”>
<a t t r i b u t e name=” numbered ” v a l u e=” f a l s e ” />
<a t t r i b u t e name=” s y m b o l i n d e n t ” v a l u e=” 0 ” />
<a t t r i b u t e name=” l i s t s y m b o l ” v a l u e=” o ” />
<a t t r i b u t e name=” s y m b o l i n d e n t ” v a l u e=” 15 ” />
</ t a g>
<t a g name=” l i s t i t e m ” a l i a s=”LINES”>
<a t t r i b u t e name=” s i z e ” v a l u e=” 11 ” />
<a t t r i b u t e name=” a l i g n ” v a l u e=” L e f t ” />
<a t t r i b u t e name=” s t y l e ” v a l u e=” i t a l i c ” />
</ t a g>
</ tagmap>
Filipe Luis
Fachhochschule Aargau
22
A. Source Code
A.1. PdfCotnentByte
Listing PdfContentByteDemo.java:
import j a v a . i o . F i l e O u t p u t S t r e a m ;
import j a v a . i o . IOException ;
import
import
import
import
com .
com .
com .
com .
lowagie
lowagie
lowagie
lowagie
.
.
.
.
text
text
text
text
.∗;
. p d f . BaseFont ;
. p d f . PdfContentByte ;
. p d f . PdfWrite r ;
/∗
∗ F i l i p e Luis , IA01
∗
∗ F a c h h o c h s c h u l e Aargau , 1 6 . 0 4 . 2 0 0 4
∗
∗/
public c l a s s ContentByteDemo
{
public s t a t i c void main ( S t r i n g [ ] a r g s )
{
// − − 1. S c h r i t t : Document I n s t a n z
Document doc = new Document ( ) ;
try
{
// − − 2. S c h r i t t : Writer e r z e u g e n
PdfWrite r w r i t e r =
PdfWrite r . g e t I n s t a n c e (
doc ,
new F i l e O u t p u t S t r e a m ( ” ContentByteDemo . p d f ” ) ) ;
// − − 3. S c h r i t t : Dokumentö f f n e n
HeaderFooter header =
new H e a d e r F o o t e r (new Phrase ( ” B e i s p i e l ContentByteDemo ” ) , f a l s e ) ;
doc . s e t H e a d e r ( h e a d e r ) ;
doc . open ( ) ;
// − − 4. S c h r i t t : I n h a l t ü h i n z u f g e n
PdfContentByte cb = w r i t e r . g e t D i r e c t C o n t e n t ( ) ;
PdfContentByte cbu = w r i t e r . g e t D i r e c t C o n t e n t U n d e r ( ) ;
BaseFont b f =
BaseFont . c r e a t e F o n t (
BaseFont . HELVETICA,
BaseFont . CP1252 ,
BaseFont .NOT EMBEDDED) ;
cb . b e g i n T e x t ( ) ;
cb . s e t F o n t A n d S i z e ( bf , 1 4 ) ;
cb . s e t T e x t M a t r i x ( 0 , 0 ) ;
Filipe Luis
Fachhochschule Aargau
A.2. Listen
23
cb . showText ( ” Urspung K o o d r i n a t e n s y s t e m ( 0 , 0 ) . ” ) ;
cb . s e t T e x t M a t r i x ( 1 0 0 , 7 0 0 ) ;
cb . showText ( ” Text a t p o s i t i o n 1 0 0 , 7 0 0 . ” ) ;
f i n a l f l o a t p i 4 = ( f l o a t ) ( Math . s q r t ( 2 ) / 2 . 0 ) ;
cb . s e t T e x t M a t r i x ( 2 , 0 , 0 , 2 , 2 0 0 , 5 0 0 ) ;
cb . showText ( ” H e l l o Audience ! ” ) ;
cb . s e t T e x t M a t r i x ( 1 . 5 f , p i 4 , − p i 4 , 1 . 5 f , 2 0 0 , 5 0 0 ) ;
cb . showText ( ” H e l l o Audience ! ” ) ;
cb . s e t T e x t M a t r i x ( 0 , 1 , − 1 , 0 , 2 0 0 , 5 0 0 ) ;
cb . showText ( ” H e l l o Audience ! ” ) ;
cb . s e t T e x t M a t r i x ( 1 0 0 , 4 5 0 ) ;
cb . showText ( ” T e s s i n , Oktober 2003 ” ) ;
//−− B i l d s o l l u n m i t t e l b a r nach Text e r s c h e i n e n cb . getYTLM ( ) . . .
Image image = Image . g e t I n s t a n c e ( ” a b s o l u t e . j p g ” ) ;
image . s c a l e P e r c e n t ( 2 0 ) ;
f l o a t x = cb . getXTLM ( ) ;
f l o a t y = cb . getYTLM ( ) − ( 6 + image . p l a i n H e i g h t ( ) ) ;
System . out . p r i n t l n (
” Absolute P o s i t i o n of Picture i s : ( ” + x + ” , ” + y + ” ) ” ) ;
image . s e t A b s o l u t e P o s i t i o n ( x , y ) ;
doc . add ( image ) ;
cbu . s e t F o n t A n d S i z e ( bf , 1 6 ) ;
cbu . s e t T e x t M a t r i x ( 1 0 , 4 0 0 ) ;
cbu . showText ( ” H i n t e r dem B i l d ( T e s s i n , Oktober 2 0 0 3 ) ” ) ;
cb . endText ( ) ;
Font p f o n t = new Font ( Font . HELVETICA, 1 4 , Font . ITALIC ) ;
Paragraph p = new Paragraph (new Phrase ( ” Durch i n t e r n e r Layer g e s e t z t ” , p f o n t ) ) ;
p . setLeading ( 1 2 ) ;
doc . add ( p ) ;
// − − 5. S c h r i t t : Dokument s c h l i e s s e n
doc . c l o s e ( ) ;
System . out . p r i n t l n ( ” ContentByteDemo . p d f c r e a t e d ! ” ) ;
}
catch ( DocumentException e )
{
e . printStackTrace ( ) ;
}
catch ( IOException e )
{
e . printStackTrace ( ) ;
}
}
}
A.2. Listen
Listing ListDemo.java:
import j a v a . i o . F i l e O u t p u t S t r e a m ;
import j a v a . i o . IOException ;
import com . l o w a g i e . t e x t . ∗ ;
import com . l o w a g i e . t e x t . p d f . PdfWrite r ;
Filipe Luis
Fachhochschule Aargau
A.3. Servlets
24
/∗
∗ F i l i p e Luis , IA01
∗
∗ F a c h h o c h s c h u l e Aargau , 1 6 . 0 4 . 2 0 0 4
∗
∗/
public c l a s s ListDemo
{
public s t a t i c void main ( S t r i n g [ ] a r g s )
{
// − − 1. S c h r i t t : Document I n s t a n z
Document doc = new Document ( ) ;
try
{
// − − 2. S c h r i t t : Writer e r z e u g e n
PdfWrite r . g e t I n s t a n c e ( doc , new F i l e O u t p u t S t r e a m ( ” ListDemo . p d f ” ) ) ;
// − − 3. S c h r i t t : Dokumentö f f n e n
doc . open ( ) ;
// − − 4. S c h r i t t : I n h a l t ü h i n z u f g e n
L i s t l i s t = new L i s t ( f a l s e , 1 5 ) ;
l i s t . setListSymbol ( ”o” ) ;
l i s t . add (new L i s t I t e m ( ” E r s t e s Element ” ) ) ;
L i s t s u b l i s t = new L i s t ( true , 2 0 ) ;
s u b l i s t . add (new L i s t I t e m ( ” E r s t e s Subelement ” ) ) ;
s u b l i s t . add (
new L i s t I t e m ( ” Z w e i t e s Subelement : B e s o n d e r s ”
+ ” l a n g damit w i r sehen , wie d i e Z e i l e i n L i s t e n umgebrochen wird . ” ) ) ;
s u b l i s t . add (new L i s t I t e m ( ” D r i t t e s Subelement ” ) ) ;
l i s t . add ( s u b l i s t ) ;
l i s t . add (new L i s t I t e m ( ” Z w e i t e s und l e t z t e s Element ” ) ) ;
doc . add ( l i s t ) ;
// − − 5. S c h r i t t : Dokument s c h l i e s s e n
doc . c l o s e ( ) ;
System . out . p r i n t l n ( ” ListDemo . p d f c r e a t e d ! ” ) ;
}
catch ( DocumentException e )
{
e . printStackTrace ( ) ;
}
catch ( IOException e )
{
e . printStackTrace ( ) ;
}
}
}
A.3. Servlets
Listing ITextServlet.java:
import j a v a . awt . C o l o r ;
import j a v a . i o . ∗ ;
import j a v a . s q l . ∗ ;
import j a v a x . s e r v l e t . ∗ ;
import j a v a x . s e r v l e t . h t t p . ∗ ;
Filipe Luis
Fachhochschule Aargau
A.3. Servlets
import
import
import
import
import
import
import
import
import
com .
com .
com .
com .
com .
com .
com .
com .
com .
25
lowagie
lowagie
lowagie
lowagie
lowagie
lowagie
lowagie
lowagie
lowagie
.
.
.
.
.
.
.
.
.
text
text
text
text
text
text
text
text
text
. Document ;
. DocumentException ;
. Font ;
. FontFactory ;
. Paragraph ;
. Phrase ;
. pdf . PdfPCell ;
. p d f . PdfPTable ;
. p d f . PdfWrite r ;
public c l a s s I T e x t S e r v l e t extends H t t p S e r v l e t
{
private C o n n e c t i o n dbcon ; // Connection f o r s c o p e o f ShowBedrock
//−− I n i t Methode : Aufbau e i n e r D a t e n b a n k v e r b i n d u n g
public void i n i t ( S e r v l e t C o n f i g c o n f i g ) throws S e r v l e t E x c e p t i o n
{
//−− Login angaben
String loginUser = ” postgres ” ;
String loginPasswd = ” i t e x t ” ;
String loginUrl =
” j d b c : p o s t g r e s q l : / / d a 8 2 6 0 i . c s . fh−a ar ga u . ch : 5 4 3 2 / i t e x t ” ;
//−− Laden d e s PostgreSQL T r e i b e r s
try
{
C l a s s . forName ( ” o r g . p o s t g r e s q l . D r i v e r ” ) ;
dbcon =
DriverManager . g e t C o n n e c t i o n ( l o g i n U r l , l o g i n U s e r , l o g i n P a s s w d ) ;
}
catch ( ClassNotFoundException ex )
{
System . out . p r i n t l n ( ” ClassNotFoundEx ” ) ;
System . e r r . p r i n t l n ( ” ClassNotFoundException : ” + ex . g e t M e s s a g e ( ) ) ;
throw new S e r v l e t E x c e p t i o n ( ” C l a s s not found E r r o r ” ) ;
}
catch ( SQLException ex )
{
System . out . p r i n t l n ( ”SQLEx” ) ;
System . e r r . p r i n t l n ( ” SQLException : ” + ex . g e t M e s s a g e ( ) ) ;
}
}
//−− I m p l e m e n t a t i o n d e s GET R e q u e s t s
public void doGet ( H t t p S e r v l e t R e q u e s t r e q u e s t , H t t p S e r v l e t R e s p o n s e r e s p o n s e )
throws IOException , S e r v l e t E x c e p t i o n
{
ByteArrayOutputStream bstream = createPDFByteArrayStream ( ) ;
r e s p o n s e . setContentType ( ” a p p l i c a t i o n / p d f ” ) ; //−− Response Mime Typ
r e s p o n s e . s e t H e a d e r ( ” Content−d i s p o s i t i o n ” , ” i n l i n e ; s t u d e n t s . p d f ” ) ;
r e s p o n s e . s e t C o n t e n t L e n g t h ( bstream . s i z e ( ) ) ;
ServletOutputStream sos ;
s o s = r e s p o n s e . getOutputStream ( ) ;
bstream . w ri te To ( s o s ) ;
sos . flush ( ) ;
}
private ByteArrayOutputStream createPDFByteArrayStream ( )
{
ByteArrayOutputStream bstream = n u l l ;
try
{
//−− S t a t e m e n t v o r b e r e i t n e
Statement s t a t e m e n t = dbcon . c r e a t e S t a t e m e n t ( ) ;
S t r i n g query = ”SELECT ∗ ” ;
query += ”FROM
employee ” ;
Filipe Luis
Fachhochschule Aargau
A.3. Servlets
26
//−− Query ü a u s f h r e n
R e s u l t S e t r s = s t a t e m e n t . e x e c u t e Q u e r y ( query ) ;
//−− PDF Dokument e r z e u g e n
Document doc = new Document ( ) ;
doc . addAuthor ( ” F i l i p e L u i s ” ) ;
bstream = new ByteArrayOutputStream ( ) ;
PdfWrite r w r i t e r = P d f W r i t e r . g e t I n s t a n c e ( doc , bstream ) ;
doc . open ( ) ;
Phrase p h r a s e =
new Phrase (
” Studenten ” ,
FontFactory . g e t F o n t (
FontFactory . HELVETICA,
32 ,
Font .BOLD | Font . ITALIC ) ) ;
PdfPTable t a b l e = new PdfPTable ( 3 ) ;
P d f P C e l l c e l l = new P d f P C e l l ( p h r a s e ) ;
c e l l . setColspan ( 3 ) ;
table . addCell ( c e l l ) ;
i n t count = 0 ;
S t r i n g [ ] s = { ”name” , ” dept ” , ” j o b t i t l e ” } ;
Font f o n t = new Font ( Font . HELVETICA, 1 8 , Font . BOLDITALIC ) ;
//−− DB ä E i n t r g e i n T a b e l l e ü e i n f g e n
while ( r s . n e x t ( ) )
{
f o r ( i n t i = 0 ; i < s . l e n g t h ; i ++)
{
String entry = rs . getString ( s [ i ] ) ;
p h r a s e = new Phrase ( e n t r y , f o n t ) ;
c e l l = new P d f P C e l l ( p h r a s e ) ;
i f ( count % 2 == 0)
c e l l . s e t B a c k g r o u n d C o l o r (new C o l o r ( 0 , 1 5 5 , 2 5 5 ) ) ;
table . addCell ( c e l l ) ;
}
count++;
}
doc . add ( t a b l e ) ;
doc . add (
new Paragraph ( 1 8 , ” C r e a t e d on : ” + new j a v a . u t i l . Date ( ) , f o n t ) ) ;
doc . c l o s e ( ) ;
}
catch ( DocumentException e )
{
System . e r r . p r i n t l n ( e . g e t M e s s a g e ( ) ) ;
}
catch ( E x c e p t i o n ex )
{
System . e r r . p r i n t l n ( ex . g e t M e s s a g e ( ) ) ;
}
return bstream ;
}
}
Filipe Luis
Fachhochschule Aargau
Literaturverzeichnis
[1] Dynamically Crating PDFs in a Web Application. Article on http://www.onjava.com/, Zuletzt geprüft im Mai 2004.
[2] iText Tutorial. http://itext.sourceforge.net/docs/, Zuletzt geprüft im Mai 2004.
[3] iText Website. http://www.lowagie.com/iText/download.html, Zuletzt geprüft im Mai
2004.
[4] iTextSharp. http://itextsharp.sourceforge.net, Zuletzt geprüft im Mai 2004.
[5] Java Servlets, JSP, Jakarta-Tomcat, Database, Apache and Linux.
http://www.yolinux.com/TUTORIALS/, Zuletzt geprüft im Mai 2004.
Article on
[6] The PostgreSQL Database and Linux. Article on http://www.yolinux.com/TUTORIALS/,
Zuletzt geprüft im Mai 2004.
27