Création de fichiers PDF en Java

Création de fichiers PDF en Java

1. introduction

Dans cet article rapide, nous nous concentrerons sur la création de documents PDF à partir de zéro, basés sur les bibliothèques iText et PdfBox populaires.

2. Dépendances Maven

Jetons un coup d'œil aux dépendances Maven, qui doivent être incluses dans notre projet:


    com.itextpdf
    itextpdf
    5.5.10


    org.apache.pdfbox
    pdfbox
    2.0.4

La dernière version des bibliothèques peut être trouvée ici:iText etPdfBox.

Une dépendance supplémentaire est nécessaire à ajouter, au cas où notre fichier aurait besoin d'être crypté. Le paquet Bounty Castle Provider contient des implémentations d'algorithmes cryptographiques et est requis par les deux bibliothèques:


    org.bouncycastle
    bcprov-jdk15on
    1.56

La dernière version de la bibliothèque se trouve ici:The Bounty Castle Provider.

3. Vue d'ensemble

IText et PdfBox sont des bibliothèques java utilisées pour la création / manipulation de fichiers PDF. Bien que le résultat final des bibliothèques soit le même, elles fonctionnent de manière légèrement différente. Jetons-y un œil.

4. Créer un PDF dans IText

4.1. Insérer du texte en PDF

Voyons comment un nouveau fichier avec le texte "Hello World" est inséré dans un fichier pdf

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();

La création d'un pdf avec une utilisation de la bibliothèque iText est basée sur la manipulation d'objets implémentant l'interfaceElements dansDocument (dans la version 5.5.10 il y a 45 de ces implémentations).

Le plus petit élément qui peut être ajouté au document et utilisé est appeléChunk, qui est essentiellement une chaîne avec une police appliquée.

De plus, lesChunk peuvent être combinés avec d'autres éléments tels queParagraphs,Section, etc. résultant en beaux documents.

4.2. Insérer une image

La bibliothèque iText offre un moyen simple d’ajouter une image au document. Nous devons simplement créer une instance deImage et l'ajouter auxDocument.

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. Insérer un tableau

Nous pourrions faire face à un problème lorsque nous voudrions ajouter un tableau à notre pdf. Heureusement, iText fournit une telle fonctionnalité prête à l'emploi.

Tout d'abord, nous devons créer un objetPdfTable et dans le constructeur, fournir un certain nombre de colonnes pour notre table. Maintenant, nous pouvons simplement ajouter une nouvelle cellule en appelant

Maintenant, nous pouvons simplement ajouter une nouvelle cellule en appelant la méthodeaddCell sur l'objet table nouvellement créé. iText créera des lignes de tableau aussi longtemps que toutes les cellules nécessaires seront définies. Cela signifie qu'une fois que vous aurez créé un tableau à 3 colonnes et ajouté 8 cellules, seules 2 lignes de 3 cellules seront affichées.

Jetons un œil à l'exemple:

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();

Nous créons une nouvelle table avec 3 colonnes et 3 lignes. La première ligne que nous traiterons comme un en-tête de tableau avec une couleur d’arrière-plan et une largeur de bordure modifiées:

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);
    });
}

La deuxième ligne sera composée de trois cellules avec uniquement du texte, sans mise en forme supplémentaire.

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

Nous pouvons inclure non seulement du texte dans des cellules, mais également des images. De plus, chaque cellule peut être formatée individuellement. Dans l'exemple présenté ci-dessous, nous appliquons des ajustements d'alignement horizontal et vertical:

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. Chiffrement de fichiers

Pour appliquer l'autorisation à l'aide de la bibliothèque iText, vous devez avoir déjà créé un document pdf. Dans notre exemple, nous utiliserons notre fichieriTextHelloWorld.pdf généré précédemment.

Une fois que nous avons chargé le fichier en utilisantPdfReader, nous devons créer unPdfStamper qui est utilisé pour appliquer un contenu supplémentaire au fichier comme les métadonnées, le cryptage, etc.:

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();

Dans notre exemple, nous avons chiffré le fichier avec deux mots de passe. Le mot de passe de l'utilisateur («userpass») sur lequel un utilisateur ne dispose que d'un droit de lecture, sans possibilité de l'imprimer, ainsi que du mot de passe du propriétaire («ownerpass») utilisé comme clé principale permettant à une personne d'avoir un accès complet au pdf.

Si nous voulons permettre à l'utilisateur d'imprimer le pdf, au lieu de 0 (troisième paramètre desetEncryption) nous pouvons passer:

PdfWriter.ALLOW_PRINTING

Bien sûr, nous pouvons mélanger différentes autorisations telles que:

PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY

N'oubliez pas qu'en utilisant iText pour définir les autorisations d'accès, nous créons également un fichier PDF temporaire qui devrait être supprimé et sinon, il pourrait être entièrement accessible à quiconque.

5. Créer un PDF dans PdfBox

5.1. Insérer du texte en PDF

Contrairement auxiText, la bibliothèquePdfBox fournit une API basée sur la manipulation de flux. Il n'y a pas de classes commeChunk /Paragraph etc. La classePDDocument est une représentation Pdf en mémoire où l'utilisateur écrit des données en manipulant la classePDPageContentStream.

Jetons un œil à l'exemple de code:

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. Insérer une image

Insérer des images est simple.

Nous devons d'abord charger un fichier et créer unPDImageXObject, puis le dessiner sur le document (besoin de fournir les coordonnées exactes x, y).

C'est tout:

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. Insérer un tableau

Malheureusement,PdfBox ne fournit aucune méthode prête à l'emploi permettant de créer des tables. Ce que nous pouvons faire dans une telle situation est de le dessiner manuellement - littéralement, tracez chaque ligne jusqu'à ce que notre dessin ressemble à la table de nos rêves.

5.4. Chiffrement de fichiers

La bibliothèquePdfBox offre la possibilité de crypter et d'ajuster l'autorisation de fichier pour l'utilisateur. Comparé àiText, il ne nécessite pas d'utiliser un fichier déjà existant, car nous utilisons simplementPDDocument. Les autorisations de fichiers PDF sont gérées par la classeAccessPermission, où nous pouvons définir si un utilisateur pourra modifier, extraire du contenu ou imprimer un fichier.

Ensuite, nous créons un objetStandardProtectionPolicy qui ajoute une protection par mot de passe au document. Nous pouvons spécifier deux types de mot de passe. Le mot de passe de l'utilisateur, après quoi la personne pourra ouvrir un fichier avec les autorisations d'accès appliquées et le mot de passe du propriétaire (aucune limitation pour le fichier):

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();

Notre exemple présente une situation dans laquelle, si un utilisateur fournit un mot de passe, le fichier ne peut pas être modifié et imprimé.

6. Conclusions

Dans ce tutoriel, nous avons discuté des moyens de créer un fichier pdf dans deux bibliothèques Java populaires.

Des exemples complets peuvent être trouvés dans le projet basé sur Mavenover on GitHub.