Membuat File PDF di Java

1. Perkenalan

Dalam artikel singkat ini, kami akan fokus pada pembuatan dokumen PDF dari awal berdasarkan pustaka iText dan PdfBox yang populer.

2. Ketergantungan Maven

Mari kita lihat dependensi Maven, yang perlu disertakan dalam proyek kita:

 com.itextpdf itextpdf 5.5.10   org.apache.pdfbox pdfbox 2.0.4 

Versi terbaru perpustakaan dapat ditemukan di sini: iText dan PdfBox.

Satu ketergantungan tambahan perlu ditambahkan, jika file kita perlu dienkripsi. Paket Penyedia Bounty Castle berisi implementasi algoritma kriptografi dan dibutuhkan oleh kedua pustaka:

 org.bouncycastle bcprov-jdk15on 1.56  

Versi terbaru dari perpustakaan dapat ditemukan di sini: Penyedia Bounty Castle.

3. Ikhtisar

Baik iText dan PdfBox adalah perpustakaan java yang digunakan untuk pembuatan / manipulasi file pdf. Meskipun hasil akhir dari pustaka adalah sama, mereka beroperasi dengan cara yang sedikit berbeda. Mari kita lihat.

4. Buat Pdf di IText

4.1. Sisipkan Teks dalam Pdf

Mari kita lihat, cara file baru dengan teks "Hello World" dimasukkan ke dalam file 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();

Membuat pdf dengan menggunakan pustaka iText didasarkan pada manipulasi objek yang mengimplementasikan antarmuka Elemen dalam Dokumen (dalam versi 5.5.10 ada 45 implementasi tersebut).

Elemen terkecil yang dapat ditambahkan ke dokumen dan digunakan disebut Chunk , yang pada dasarnya adalah string dengan font yang diterapkan.

Selain itu, Chunk dapat dikombinasikan dengan elemen lain seperti Paragraphs , Section dll. Menghasilkan dokumen yang terlihat bagus.

4.2. Memasukkan Gambar

Perpustakaan iText menyediakan cara mudah untuk menambahkan gambar ke dokumen. Kita hanya perlu membuat instance Image dan menambahkannya ke Dokumen .

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. Memasukkan Tabel

Kami mungkin menghadapi masalah saat kami ingin menambahkan tabel ke pdf kami. Untungnya iText menyediakan fungsionalitas yang out-of-the-box.

Pertama yang perlu kita lakukan adalah membuat objek PdfTable dan dalam konstruktor menyediakan sejumlah kolom untuk tabel kita. Sekarang kita cukup menambahkan sel baru dengan menelepon

Sekarang kita cukup menambahkan sel baru dengan memanggil metode addCell pada objek tabel yang baru dibuat. iText akan membuat baris tabel selama semua sel yang diperlukan telah ditentukan, artinya setelah Anda membuat tabel dengan 3 kolom dan menambahkan 8 sel ke dalamnya, hanya 2 baris dengan 3 sel di masing-masing yang akan ditampilkan.

Mari kita lihat contohnya:

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

Kami membuat tabel baru dengan 3 kolom dan 3 baris. Baris pertama yang akan kita perlakukan sebagai header tabel dengan warna latar belakang dan lebar batas yang diubah:

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

Baris kedua akan terdiri dari tiga sel hanya dengan teks, tanpa format tambahan.

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

Kami tidak hanya dapat memasukkan teks dalam sel tetapi juga gambar. Selain itu, setiap sel dapat diformat secara individual, dalam contoh yang disajikan di bawah ini kami menerapkan penyesuaian perataan horizontal dan vertikal:

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. Enkripsi File

Untuk mengajukan izin menggunakan pustaka iText, kita harus sudah membuat dokumen pdf. Dalam contoh kami, kami akan menggunakan file iTextHelloWorld.pdf kami yang dibuat sebelumnya.

Setelah kami memuat file menggunakan PdfReader , kami perlu membuat PdfStamper yang digunakan untuk menerapkan konten tambahan ke file seperti metadata, enkripsi, dll:

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

Dalam contoh kami, kami mengenkripsi file dengan dua kata sandi. Kata sandi pengguna ("userpass") di mana pengguna hanya memiliki hak baca-saja tanpa kemungkinan untuk mencetaknya, dan kata sandi pemilik ("ownerpass") yang digunakan sebagai kunci utama yang memungkinkan seseorang memiliki akses penuh ke pdf.

Jika kita ingin mengizinkan pengguna untuk mencetak pdf, alih-alih 0 (parameter ketiga setEncryption ) kita dapat meneruskan:

PdfWriter.ALLOW_PRINTING

Tentu saja, kami dapat menggabungkan izin yang berbeda seperti:

PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY

Perlu diingat bahwa menggunakan iText untuk mengatur izin akses, kami juga membuat pdf sementara yang harus dihapus dan jika tidak, itu dapat sepenuhnya diakses oleh siapa saja.

5. Buat Pdf di PdfBox

5.1. Sisipkan Teks dalam Pdf

Berbeda dengan iText , pustaka PdfBox menyediakan API yang didasarkan pada manipulasi aliran. Tidak ada kelas seperti Chunk / Paragraph dll. Kelas PDDocument adalah representasi Pdf dalam memori di mana pengguna menulis data dengan memanipulasi kelas PDPageContentStream .

Mari kita lihat contoh kode:

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. Memasukkan Gambar

Memasukkan gambar sangatlah mudah.

First we need to load a file and create a PDImageXObject, subsequently draw it on the document (need to provide exact x,y coordinates).

That's all:

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. Inserting a Table

Unfortunately, PdfBox does not provide any out-of-box methods allowing creating tables. What we can do in such situation is to draw it manually – literally, draw each line until our drawing resembles our dreamed table.

5.4. File Encryption

PdfBox library provides a possibility to encrypt, and adjust file permission for the user. Comparing to iText, it does not require to use an already existing file, as we simply use PDDocument. Pdf file permissions are handled by AccessPermission class, where we can set if a user will be able to modify, extract content or print a file.

Subsequently, we create a StandardProtectionPolicy object which adds password-based protection to the document. We can specify two types of password. The user password, after which person will be able to open a file with applied access permissions and owner password (no limitations to the file):

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

Contoh kami menyajikan situasi bahwa jika pengguna memberikan kata sandi pengguna, file tidak dapat dimodifikasi dan dicetak.

6. Kesimpulan

Dalam tutorial ini, kami membahas cara membuat file pdf di dua perpustakaan Java yang populer.

Contoh lengkap dapat ditemukan di proyek berbasis Maven di GitHub.