Wie lässt sich eine Tabelle als *.pdf ausgeben?
Das Beispiel enthält neben der main-Methode den Konstruktor und
die Methode writePDF()
, die für das Drucken der
Tabelle in die PDF-Datei verantwortlich zeichnet. Im Konstruktor
wird das Hauptfenster erzeugt, auf das eine einfache JTable
und ein JButton
zum Anstoßen der
Druckfunktionalität geladen werden.
Die auszugebende
Tabelle stellt zu Demonstrationszwecken nur ein einfaches Beispiel
dar und wird wie üblich durch ein Model mit Inhalt versehen.
Das DefaultTableModel
wird hierbei durch ein
eindimensionales String-Array für die Spaltentitel und ein
zweidimensionales für den eigentlichen Inhalt gefüllt.
Nach Erzeugen der Umrandung wird die Tabelle erst auf ein Scrollpane
und mit diesem ins Zentrum des Frames geladen.
Ein Button im
unteren Teil des Frames ruft in einer anonymen ActionListener
-Klasse die Methode writePDF()
auf, die für die
Funktionalität der PDF-Ausgabe verantwortlich ist. Ihr werden
drei Parameter übergeben: der Dateiname der Ausgabedatei, das
Tabellen-Model und das Array der Spaltennamen.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.util.GregorianCalendar;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class PDFTable {
private static final String SAVE_PATH = "/Users/joecze/Downloads/";
private static final String SAVE_FILE_NAME = "Test.pdf";
private static final String TABLE_TITLE = "PDF-Table";
public PDFTable() {
initGUI();
}
private void initGUI() {
final String[] colNames = new String[] { "eins", "zwei", "drei" };
String[][] data = new String[][] {
new String[] { "1.1", "1.2", "1.3" },
new String[] { "2.1", "2.2", "2.3" },
new String[] { "3.1", "3.2", "3.3" } };
final DefaultTableModel model = new DefaultTableModel(data, colNames);
JTable table = new JTable(model);
table.setShowGrid(true);
table.setGridColor(Color.LIGHT_GRAY);
JFrame frame = new JFrame(TABLE_TITLE);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
JButton butt = new JButton("PDF drucken");
butt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
writePDF(SAVE_PATH + SAVE_FILE_NAME, model, colNames);
}
});
frame.add(butt, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void writePDF(final String fileName, final DefaultTableModel model,
final String[] colNames) {
if (model == null) {
System.err.println("Couldn't save table as *.pdf: model is null");
return;
}
Thread t = new Thread() {
public void run() {
PdfPTable table = new PdfPTable(model.getColumnCount());
table.setWidthPercentage(100);
// Titel
DateFormat df = DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT);
Paragraph head = new Paragraph("Tabledemo - "
+ df.format(new GregorianCalendar().getTime()),
new Font(FontFamily.HELVETICA, 14, Font.BOLD));
head.setSpacingAfter(15f);
// Spaltentitel
for (int i = 0; i < colNames.length; i++) {
PdfPCell cell = new PdfPCell(new Phrase(colNames[i], new Font(
FontFamily.HELVETICA, 10)));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
table.addCell(cell);
}
// Tabelleninhalt
table.getDefaultCell().enableBorderSide(PdfPCell.BOX);
int cols = model.getColumnCount(), rows = model.getRowCount();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
String value = model.getValueAt(i, j).toString();
table.addCell(new Phrase(value, new Font(
FontFamily.HELVETICA, 10)));
}
}
Document document = new Document(PageSize.A4.rotate(), 20, 15,
15, 15);
try {
PdfWriter.getInstance(document, new FileOutputStream(
fileName));
document.open();
document.add(head);
document.add(table);
document.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
};
t.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PDFTable());
}
}
Die Ausgabe des PDF wird in einen eigenen Thread ausgelagert, um bei
langen Ausgabeprozessen den Programmfluss nicht zu blockieren. Er
wird noch in der Methode selbst gestartet. Die run-Methode des
Threads enhält die gesamte Funktionalität und beginnt mit
der Erzeugung eines PdfPTable
-Objektes, dem Objekt,
das für die Darstellung der Tabelle in der PDF-Datei
zuständig ist. Dem Konstruktor werden zwei Parameter
übergeben: die Spaltenzahl und die Gesamtbreite der Tabelle,
bezogen auf die Dokumentbreite.
Die Methode PdfPTable.getDefaultCell()
liefert ein Objekt der 'Standard-Tabellenzelle', die in die Tabelle
gesetzt wird, wenn dieser kein spezifisches PdfPCell
-Objekt übergeben wird. Sie wird über die statische
Variable BOX mit einem Rand versehen.
In der Folge wird die Seitenüberschrift gesetzt. Sie erfolgt im
Rahmen eines Paragraph
-Objektes, das etwa einem
Abschnitt entspricht. Ihm wird ein String übergeben, der hier
u.a. ein auf der Klasse GregorianCalendar
beruhendes
Datum enhält. SetSpacingAfter()
erzeugt einen
Abstand in Höhe des übergebenen float
-Wertes
nach dem zugehörigen Abschnitt.
Die beiden folgenden Quelltext-Absätze zeigen das
Hinzufügen der Spaltentitel und des Tabelleninhaltes zum
Tabellen-Objekt. Zentrale Methode ist hierbei PdfPTable.addCell()
. Sie existiert in mehreren überladenen Varianten, von denen
zwei hier demonstriert werden: Bei den Spaltentiteln wird ein PdfPCell
-Objekt übergeben, das zunächst gebildet werden muss und
hierbei als Parameter ein Phrase
-Objekt erhält,
das wiederum neben dem Inhalt als String noch den Schrifttyp genannt
bekommt. Die Hintergrundfarbe kann zusätzlich durch setBackgroundColor()
definiert werden.
Im zweiten Fall, der Erzeugung des
Tabelleninhaltes, wird der Methode addCell
direkt das Phrase
-Objekt übergeben. Mit diesem Schritt ist die Bildung des
Tabellen-Objektes abgeschlossen.
Den Abschluss bilden die Erstellung eines Document
-Objektes und dessen Export. Ersteres erfolgt hier im Format DIN
A4, das durch PageSize.A4.rotate()
als Querformat
spezifiziert wird. Die anderen Parameter des Konstruktors geben die
Abstände des Dokument-Inhaltes vom Papierrand in Pixeln in der
Reihenfolge links, rechts, oben, unten an. Der Export erfolgt durch
den Aufruf eines PdfWriter
-Singletons, dem das
Dokument und ein FileOutputStream
mit dem
Ziel-Dateinamen übergeben wird.
Ist das Objekt gebildet,
wird das Dokument geöffnet, die Textteile werden eingefügt
und anschließend wird es wieder geschlossen. Der Export-Vorgang
muss in einen try-catch-Block eingeschlossen werden, um Probleme
beim Export und bei der Erzeugung des Dokumentes abzufangen.
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.