1. Pengenalan
Dalam artikel ringkas ini, kita akan fokus membuat dokumen PDF dari awal berdasarkan perpustakaan iText dan PdfBox yang popular.
2. Pergantungan Maven
Mari lihat kebergantungan Maven, yang perlu disertakan dalam projek kami:
com.itextpdf itextpdf 5.5.10 org.apache.pdfbox pdfbox 2.0.4
Versi terbaru perpustakaan boleh didapati di sini: iText dan PdfBox.
Satu kebergantungan tambahan diperlukan untuk menambahkan, sekiranya fail kita perlu disulitkan. Pakej Penyedia Istana Bounty mengandungi pelaksanaan algoritma kriptografi dan diperlukan oleh kedua perpustakaan:
org.bouncycastle bcprov-jdk15on 1.56
Versi terbaru perpustakaan boleh didapati di sini: The Bounty Castle Provider.
3. Gambaran keseluruhan
Kedua-duanya, iText dan PdfBox adalah perpustakaan java yang digunakan untuk membuat / memanipulasi fail pdf. Walaupun output akhir perpustakaan adalah sama, ia beroperasi dengan cara yang sedikit berbeza. Mari kita perhatikan mereka.
4. Buat Pdf dalam IText
4.1. Masukkan Teks dalam Pdf
Mari lihat, cara fail baru dengan teks "Hello World" dimasukkan ke dalam fail 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 penggunaan perpustakaan iText didasarkan pada memanipulasi objek yang melaksanakan antara muka Elemen dalam Dokumen (dalam versi 5.5.10 ada 45 dari 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 digabungkan dengan unsur-unsur lain seperti Perenggan , Bahagian dan lain-lain sehingga menghasilkan dokumen yang cantik.
4.2. Memasukkan Imej
Perpustakaan iText menyediakan cara mudah untuk menambahkan gambar ke dokumen. Kita hanya perlu membuat contoh Gambar 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 Jadual
Kami mungkin menghadapi masalah semasa ingin menambahkan jadual ke pdf kami. Nasib baik iText menyediakan fungsi seperti itu.
Pertama yang perlu kita buat ialah membuat objek PdfTable dan dalam konstruktor menyediakan sebilangan lajur untuk jadual kita. Sekarang kita boleh menambah sel baru dengan memanggil
Sekarang kita boleh menambahkan sel baru dengan memanggil kaedah addCell pada objek jadual yang baru dibuat. iText akan membuat baris jadual selagi semua sel yang diperlukan ditentukan, maksudnya ialah apabila anda membuat jadual dengan 3 lajur dan menambahkan 8 sel padanya, hanya 2 baris dengan 3 sel di setiap satu akan ditampilkan.
Mari 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 jadual baru dengan 3 lajur dan 3 baris. Baris pertama yang akan kami laksanakan sebagai tajuk meja dengan warna latar belakang dan lebar sempadan yang berubah:
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 pemformatan 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 memasukkan teks dalam sel tetapi juga gambar. Selain itu, setiap sel mungkin diformat secara berasingan, dalam contoh yang ditunjukkan di bawah ini kami menerapkan penyesuaian penjajaran mendatar dan menegak:
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. Penyulitan Fail
Untuk memohon kebenaran menggunakan perpustakaan iText, kita harus sudah membuat dokumen pdf. Dalam contoh kami, kami akan menggunakan fail iTextHelloWorld.pdf yang dihasilkan sebelumnya.
Setelah memuatkan fail menggunakan PdfReader , kita perlu membuat PdfStamper yang digunakan untuk menerapkan kandungan 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 menyulitkan fail dengan dua kata laluan. Kata laluan pengguna ("userpass") di mana pengguna hanya memiliki hak baca sahaja tanpa kemungkinan mencetaknya, dan kata laluan pemilik ("ownerpass") yang digunakan sebagai kunci induk yang membolehkan seseorang mendapat akses penuh ke pdf.
Sekiranya kita ingin membenarkan pengguna mencetak pdf, bukannya 0 (parameter ketiga setEncryption ) kita boleh lulus:
PdfWriter.ALLOW_PRINTING
Sudah tentu, kita boleh mencampurkan kebenaran yang berbeza seperti:
PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY
Perlu diingat bahawa menggunakan iText untuk menetapkan izin akses, kami juga membuat pdf sementara yang harus dihapus dan jika tidak dapat diakses sepenuhnya oleh siapa pun.
5. Buat Pdf dalam PdfBox
5.1. Masukkan Teks dalam Pdf
Berbeda dengan iText , perpustakaan PdfBox menyediakan API yang berdasarkan 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 lihat contoh kod:
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 Imej
Memasukkan gambar adalah 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 menunjukkan situasi bahawa jika pengguna memberikan kata laluan pengguna, fail tidak dapat diubah dan dicetak.
6. Kesimpulan
Dalam tutorial ini, kami membincangkan cara membuat fail pdf di dua perpustakaan Java yang popular.
Contoh lengkap boleh didapati dalam projek berasaskan Maven di GitHub.