Java PDFBox
最后修改于 2024 年 1 月 27 日
Java PDFBox 教程展示了如何使用 PDFBox 在 Java 中创建 PDF 文件。
PDFBox
Apache PDFBox 是一个开源 Java 库,可用于创建、渲染、打印、分割、合并、修改、验证以及提取 PDF 文件的文本和元数据。
另一个非常流行的用于处理 PDF 文件的 Java 库是 iText。
PDFBox Maven 依赖
我们需要为我们的项目添加以下 Maven 依赖。
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.8</version> </dependency>
Java PDFBox 写入文本
在以下示例中,我们创建一个 PDF 文档并在其中写入一些文本。
package com.zetcode; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class JavaPdfBoxWriteText { public static void main(String[] args) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage myPage = new PDPage(); doc.addPage(myPage); try (PDPageContentStream cont = new PDPageContentStream(doc, myPage)) { cont.beginText(); cont.setFont(PDType1Font.TIMES_ROMAN, 12); cont.setLeading(14.5f); cont.newLineAtOffset(25, 700); String line1 = "World War II (often abbreviated to WWII or WW2), " + "also known as the Second World War,"; cont.showText(line1); cont.newLine(); String line2 = "was a global war that lasted from 1939 to 1945, " + "although related conflicts began earlier."; cont.showText(line2); cont.newLine(); String line3 = "It involved the vast majority of the world's " + "countries—including all of the great powers—"; cont.showText(line3); cont.newLine(); String line4 = "eventually forming two opposing military " + "alliances: the Allies and the Axis."; cont.showText(line4); cont.newLine(); cont.endText(); } doc.save("src/main/resources/wwii.pdf"); } } }
该示例将四行文本写入 PDF 文档。
try (PDDocument doc = new PDDocument()) {
创建一个新的 PDDocument
。 默认情况下,文档的格式为 A4。
PDPage myPage = new PDPage(); doc.addPage(myPage);
创建一个新页面并将其添加到文档中。
try (PDPageContentStream cont = new PDPageContentStream(doc, myPage)) {
要写入 PDF 页面,我们必须创建一个 PDPageContentStream
对象。
cont.beginText(); ... cont.endText();
文本在 beginText
和 endText
方法之间写入。
cont.setFont(PDType1Font.TIMES_ROMAN, 12); cont.setLeading(14.5f);
我们设置字体和文本行距。
cont.newLineAtOffset(25, 700);
我们使用 newLineAtOffset
方法开始新的文本行。 页面的原点位于左下角。
String line1 = "World War II (often abbreviated to WWII or WW2), " + "also known as the Second World War,"; cont.showText(line1);
文本使用 showText
方法写入。
cont.newLine();
使用 newLine
方法,我们移动到下一行文本的开头。
Java PDFBox 读取文本
下一个示例从 PDF 文件中读取文本。
package com.zetcode; import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; public class JavaPdfBoxReadText { public static void main(String[] args) throws IOException { File myFile = new File("src/main/resources/wwii.pdf"); try (PDDocument doc = PDDocument.load(myFile)) { PDFTextStripper stripper = new PDFTextStripper(); String text = stripper.getText(doc); System.out.println("Text size: " + text.length() + " characters:"); System.out.println(text); } } }
该示例打印 PDF 文档的文本及其大小。
File myFile = new File("src/main/resources/wwii.pdf"); try (PDDocument doc = PDDocument.load(myFile)) {
我们从 src/main/resources
目录加载 PDF 文档。
PDFTextStripper stripper = new PDFTextStripper(); String text = stripper.getText(doc);
PDFTextStripper
用于从 PDF 文件中提取文本。
Java PDFBox 创建图像
下一个示例在 PDF 文档中创建一个图像。
package com.zetcode; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; public class JavaPdfBoxCreateImage { public static void main(String[] args) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage myPage = new PDPage(); doc.addPage(myPage); String imgFileName = "src/main/resources/sid2.jpg"; PDImageXObject pdImage = PDImageXObject.createFromFile(imgFileName, doc); int iw = pdImage.getWidth(); int ih = pdImage.getHeight(); float offset = 20f; try (PDPageContentStream cont = new PDPageContentStream(doc, myPage)) { cont.drawImage(pdImage, offset, offset, iw, ih); } doc.save("src/main/resources/mydoc.pdf"); } } }
该示例从目录加载图像,创建一个新的 PDF 文档,并将图像添加到页面中。
String imgFileName = "src/main/resources/sid2.jpg"; PDImageXObject pdImage = PDImageXObject.createFromFile(imgFileName, doc);
PDImageXObject
用于在 PDFBox 中处理图像。
int iw = pdImage.getWidth(); int ih = pdImage.getHeight();
我们获取图像的宽度和高度。
try (PDPageContentStream cont = new PDPageContentStream(doc, myPage)) { cont.drawImage(pdImage, offset, offset, iw, ih); }
PDPageContentStream
的 drawImage
将图像绘制到页面中。
Java PDFBox 文档信息
PDF 文档可以包含描述文档本身或文档中某些对象的信息,例如文档的作者或其创建日期。 可以使用 PDDocumentInformation
对象设置和检索基本信息。
package com.zetcode; import java.io.IOException; import java.util.Calendar; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentInformation; import org.apache.pdfbox.pdmodel.PDPage; public class JavaPdfBoxDocumentInformation { public static void main(String[] args) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage myPage = new PDPage(); doc.addPage(myPage); PDDocumentInformation pdi = doc.getDocumentInformation(); pdi.setAuthor("Jan Bodnar"); pdi.setTitle("World war II"); pdi.setCreator("Java code"); Calendar date = Calendar.getInstance(); pdi.setCreationDate(date); pdi.setModificationDate(date); pdi.setKeywords("World war II, conflict, Allies, Axis powers"); doc.save("src/main/resources/mydoc.pdf"); } } }
该示例创建一些文档信息元数据。 该信息可以在 PDF 阅读器中 PDF 文档的属性中看到。
PDDocumentInformation pdi = doc.getDocumentInformation();
我们获取 PDDocumentInformation
对象。
pdi.setAuthor("Jan Bodnar"); pdi.setTitle("World war II"); pdi.setCreator("Java code");
我们设置一些元数据信息。
Java PDFBox 写入元数据
可扩展元数据平台 (XMP) 是一个 ISO 标准,用于创建、处理和交换数字文档和数据集的标准化和自定义元数据。 PDF 文件使用 XMP 来存储额外的元数据信息。
<?xml version="1.0" encoding="UTF-8"?> <x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <rdf:Description rdf:about=""> <dc:title>World war II</dc:title> <dc:date>2018-01-25</dc:date> <dc:author>Jan Bodnar</dc:author> </rdf:Description> </rdf:RDF> </x:xmpmeta>
这是一个 XML 文档,其中包含有关 PDF 文档的一些基本元数据。
package com.zetcode; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.common.PDMetadata; public class JavaPdfBoxMetadataWrite { public static void main(String[] args) throws IOException { try (PDDocument doc = new PDDocument()) { PDPage myPage = new PDPage(); File myFile = new File("src/main/resources/metadata.xml"); try (InputStream is = Files.newInputStream(myFile.toPath())) { PDMetadata meta = new PDMetadata(doc, is); PDDocumentCatalog catalog = doc.getDocumentCatalog(); catalog.setMetadata(meta); doc.addPage(myPage); } doc.save("src/main/resources/mydoc.pdf"); } } }
该示例从 XML 文件读取元数据并将其存储在生成的二进制文档中。
PDMetadata meta = new PDMetadata(doc, is);
PDMetadata
用于处理元数据。
PDDocumentCatalog catalog = doc.getDocumentCatalog(); catalog.setMetadata(meta);
我们将元数据设置为文档的目录。
Java PDFBox 读取元数据
在下一个示例中,我们从 PDF 文档中读取元数据。
package com.zetcode; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.common.PDMetadata; public class JavaPdfBoxMetadataRead { public static void main(String[] args) throws IOException { File myFile = new File("src/main/resources/sinatra.pdf"); try (PDDocument doc = PDDocument.load(myFile)) { PDDocumentCatalog catalog = doc.getDocumentCatalog(); PDMetadata metadata = catalog.getMetadata(); if (metadata == null) { System.err.println("No metadata in document"); System.exit(1); } try (InputStream is = metadata.createInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr)) { br.lines().forEach(System.out::println); } } } }
该示例从 PDF 文档读取元数据并将其打印到控制台。
PDDocumentCatalog catalog = doc.getDocumentCatalog(); PDMetadata metadata = catalog.getMetadata();
我们从 PDDocumentCatalog
检索 PDMetadata
。
if (metadata == null) { System.err.println("No metadata in document"); System.exit(1); }
文档可能不包含元数据;因此,我们进行一些简单的检查。
try (InputStream is = metadata.createInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr)) { br.lines().forEach(System.out::println); }
createInputStream
创建一个到文档元数据的输入流。 我们从这个流中读取数据并将其打印到终端。
来源
在本文中,我们展示了如何使用 PDFBox 库在 Java 中处理 PDF 文件。
作者
列出所有Java教程。