PDF-Dateien in Java erstellen

PDF-Dateien in Java erstellen

1. Einführung

In diesem kurzen Artikel konzentrieren wir uns darauf, PDF-Dokumente von Grund auf neu zu erstellen, basierend auf der beliebten iText- und PdfBox-Bibliothek.

2. Maven-Abhängigkeiten

Werfen wir einen Blick auf die Maven-Abhängigkeiten, die in unser Projekt aufgenommen werden müssen:


    com.itextpdf
    itextpdf
    5.5.10


    org.apache.pdfbox
    pdfbox
    2.0.4

Die neueste Version der Bibliotheken finden Sie hier:iText undPdfBox.

Eine zusätzliche Abhängigkeit ist erforderlich, um hinzuzufügen, falls unsere Datei verschlüsselt werden muss. Das Paket Bounty Castle Provider enthält Implementierungen von kryptografischen Algorithmen und wird von beiden Bibliotheken benötigt:


    org.bouncycastle
    bcprov-jdk15on
    1.56

Die neueste Version der Bibliothek finden Sie hier:The Bounty Castle Provider.

3. Überblick

Sowohl iText als auch PdfBox sind Java-Bibliotheken, die zum Erstellen / Bearbeiten von PDF-Dateien verwendet werden. Obwohl die endgültige Ausgabe der Bibliotheken identisch ist, arbeiten sie etwas anders. Schauen wir sie uns an.

4. Erstellen Sie ein PDF in IText

4.1. Text in Pdf einfügen

Schauen wir uns an, wie eine neue Datei mit dem Text "Hello World" in die PDF-Datei eingefügt wird

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("iTextHelloWorld.pdf"));

document.open();
Font font = FontFactory.getFont(FontFactory.COURIER, 16, BaseColor.BLACK);
Chunk chunk = new Chunk("Hello World", font);

document.add(chunk);
document.close();

Das Erstellen eines PDFs unter Verwendung der iText-Bibliothek basiert auf der Manipulation von Objekten, die die Schnittstelle vonElementsinDocument implementieren (in Version 5.5.10 gibt es 45 dieser Implementierungen).

Das kleinste Element, das dem Dokument hinzugefügt und verwendet werden kann, heißtChunk. Dies ist im Grunde eine Zeichenfolge mit angewendeter Schriftart.

Zusätzlich könnenChunk mit anderen Elementen wieParagraphs,Section usw. kombiniert werden. Daraus resultieren gut aussehende Dokumente.

4.2. Bild einfügen

Die iText-Bibliothek bietet eine einfache Möglichkeit, dem Dokument ein Bild hinzuzufügen. Wir müssen lediglich eineImage-Instanz erstellen und zu denDocument hinzufügen.

Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("iTextImageExample.pdf"));
document.open();
Image img = Image.getInstance(path.toAbsolutePath().toString());
document.add(img);

document.close();

4.3. Tabelle einfügen

Wir könnten auf ein Problem stoßen, wenn wir unserem PDF eine Tabelle hinzufügen möchten. Zum Glück bietet iText solche Funktionen ab Werk.

Zuerst müssen wir einPdfTable-Objekt erstellen und im Konstruktor eine Reihe von Spalten für unsere Tabelle bereitstellen. Jetzt können wir einfach eine neue Zelle hinzufügen, indem wir anrufen

Jetzt können wir einfach eine neue Zelle hinzufügen, indem wir die MethodeaddCellfür das neu erstellte Tabellenobjekt aufrufen. iText erstellt Tabellenzeilen, solange alle erforderlichen Zellen definiert sind. Wenn Sie eine Tabelle mit 3 Spalten erstellen und 8 Zellen hinzufügen, werden nur 2 Zeilen mit jeweils 3 Zellen angezeigt.

Schauen wir uns das Beispiel an:

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("iTextTable.pdf"));

document.open();

PdfPTable table = new PdfPTable(3);
addTableHeader(table);
addRows(table);
addCustomRows(table);

document.add(table);
document.close();

Wir erstellen eine neue Tabelle mit 3 Spalten und 3 Zeilen. Die erste Zeile wird als Tabellenüberschrift mit geänderter Hintergrundfarbe und Rahmenbreite behandelt:

private void addTableHeader(PdfPTable table) {
    Stream.of("column header 1", "column header 2", "column header 3")
      .forEach(columnTitle -> {
        PdfPCell header = new PdfPCell();
        header.setBackgroundColor(BaseColor.LIGHT_GRAY);
        header.setBorderWidth(2);
        header.setPhrase(new Phrase(columnTitle));
        table.addCell(header);
    });
}

Die zweite Zeile besteht aus drei Zellen, nur mit Text, ohne zusätzliche Formatierung.

private void addRows(PdfPTable table) {
    table.addCell("row 1, col 1");
    table.addCell("row 1, col 2");
    table.addCell("row 1, col 3");
}

Wir können nicht nur Text in Zellen, sondern auch Bilder einfügen. Darüber hinaus kann jede Zelle einzeln formatiert werden. Im folgenden Beispiel werden horizontale und vertikale Ausrichtungseinstellungen vorgenommen:

private void addCustomRows(PdfPTable table)
  throws URISyntaxException, BadElementException, IOException {
    Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
    Image img = Image.getInstance(path.toAbsolutePath().toString());
    img.scalePercent(10);

    PdfPCell imageCell = new PdfPCell(img);
    table.addCell(imageCell);

    PdfPCell horizontalAlignCell = new PdfPCell(new Phrase("row 2, col 2"));
    horizontalAlignCell.setHorizontalAlignment(Element.ALIGN_CENTER);
    table.addCell(horizontalAlignCell);

    PdfPCell verticalAlignCell = new PdfPCell(new Phrase("row 2, col 3"));
    verticalAlignCell.setVerticalAlignment(Element.ALIGN_BOTTOM);
    table.addCell(verticalAlignCell);
}

4.4. Dateiverschlüsselung

Um die Erlaubnis zur Verwendung der iText-Bibliothek zu erteilen, müssen wir bereits ein PDF-Dokument erstellt haben. In unserem Beispiel verwenden wir die zuvor generierteiTextHelloWorld.pdf-Datei.

Sobald wir die Datei mitPdfReader geladen haben, müssen wir einPdfStamper erstellen, mit dem zusätzliche Inhalte auf Dateien wie Metadaten, Verschlüsselung usw. angewendet werden:

PdfReader pdfReader = new PdfReader("HelloWorld.pdf");
PdfStamper pdfStamper
  = new PdfStamper(pdfReader, new FileOutputStream("encryptedPdf.pdf"));

pdfStamper.setEncryption(
  "userpass".getBytes(),
  ".getBytes(),
  0,
  PdfWriter.ENCRYPTION_AES_256
);

pdfStamper.close();

In unserem Beispiel haben wir die Datei mit zwei Passwörtern verschlüsselt. Das Benutzerkennwort ("userpass"), bei dem ein Benutzer nur Leserechte ohne Druckmöglichkeit hat, und das Besitzerkennwort ("ownerpass"), das als Hauptschlüssel verwendet wird und einer Person den uneingeschränkten Zugriff auf PDF ermöglicht.

Wenn wir dem Benutzer erlauben möchten, PDF zu drucken, können wir anstelle von 0 (dritter Parameter vonsetEncryption) Folgendes übergeben:

PdfWriter.ALLOW_PRINTING

Natürlich können wir verschiedene Berechtigungen mischen wie:

PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY

Denken Sie daran, dass wir mit iText die Zugriffsberechtigungen festlegen und ein temporäres PDF erstellen, das gelöscht werden sollte und ansonsten für jedermann uneingeschränkt zugänglich sein könnte.

5. Erstellen Sie Pdf in PdfBox

5.1. Text in Pdf einfügen

Im Gegensatz zuiText bietet die BibliothekPdfBox eine API, die auf Stream-Manipulation basiert. Es gibt keine Klassen wieChunk /Paragraph usw. Die KlassePDDocument ist eine speicherinterne PDF-Darstellung, in die der Benutzer Daten schreibt, indem er die KlassePDPageContentStreammanipuliert.

Schauen wir uns das Codebeispiel an:

PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);

PDPageContentStream contentStream = new PDPageContentStream(document, page);

contentStream.setFont(PDType1Font.COURIER, 12);
contentStream.beginText();
contentStream.showText("Hello World");
contentStream.endText();
contentStream.close();

document.save("pdfBoxHelloWorld.pdf");
document.close();

5.2. Bild einfügen

Das Einfügen von Bildern ist unkompliziert.

Zuerst müssen wir eine Datei laden und einPDImageXObject erstellen, anschließend auf das Dokument zeichnen (genaue x-, y-Koordinaten müssen angegeben werden).

Das ist alles:

PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);

Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI());
PDPageContentStream contentStream = new PDPageContentStream(document, page);
PDImageXObject image
  = PDImageXObject.createFromFile(path.toAbsolutePath().toString(), document);
contentStream.drawImage(image, 0, 0);
contentStream.close();

document.save("pdfBoxImage.pdf");
document.close();

5.3. Einfügen einer Tabelle

Leider bietetPdfBox keine sofort einsatzbereiten Methoden zum Erstellen von Tabellen. Was wir in einer solchen Situation tun können, ist, es manuell zu zeichnen - zeichnen Sie buchstäblich jede Linie, bis unsere Zeichnung unserem Traumtisch ähnelt.

5.4. Dateiverschlüsselung

Die Bibliothek vonPdfBoxbietet die Möglichkeit, die Dateiberechtigung für den Benutzer zu verschlüsseln und anzupassen. Im Vergleich zuiText muss keine bereits vorhandene Datei verwendet werden, da wir einfachPDDocument verwenden. PDF-Dateiberechtigungen werden von der KlasseAccessPermissionbehandelt, in der festgelegt werden kann, ob ein Benutzer Inhalte ändern, extrahieren oder drucken kann.

Anschließend erstellen wir einStandardProtectionPolicy-Objekt, das dem Dokument einen kennwortbasierten Schutz hinzufügt. Wir können zwei Arten von Passwörtern angeben. Das Benutzerkennwort, nach dem die Person eine Datei mit den angewendeten Zugriffsberechtigungen und dem Besitzerkennwort öffnen kann (keine Einschränkungen für die Datei):

PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);

AccessPermission accessPermission = new AccessPermission();
accessPermission.setCanPrint(false);
accessPermission.setCanModify(false);

StandardProtectionPolicy standardProtectionPolicy
  = new StandardProtectionPolicy("ownerpass", "userpass", accessPermission);
document.protect(standardProtectionPolicy);
document.save("pdfBoxEncryption.pdf");
document.close();

In unserem Beispiel wird die Situation dargestellt, dass die Datei nicht geändert und gedruckt werden kann, wenn ein Benutzer ein Benutzerkennwort angibt.

6. Schlussfolgerungen

In diesem Lernprogramm haben wir Möglichkeiten zum Erstellen einer PDF-Datei in zwei gängigen Java-Bibliotheken erörtert.

Vollständige Beispiele finden Sie im Maven-basierten Projektover on GitHub.