💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Java PDFBox 教程 原文:http://zetcode.com/java/pdfbox/ Java PDFBox 教程展示了如何使用 PDFBox 在 Java 中创建 PDF 文件。 ## PDFBox Apache PDFBox 是一个开源 Java 库,可用于创建,渲染,打印,拆分,合并,更改,验证和提取 PDF 文件的文本和元数据。 另一个非常流行的用于处理 PDF 文件的 Java 库称为 iText 。 ## PDFBox Maven 依赖项 我们需要为我们的项目添加以下 Maven 依赖项。 ```java <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.8</version> </dependency> ``` ## Java PDFBox 写文本 在下面的示例中,我们创建一个 PDF 文档并将一些文本写入其中。 `JavaPdfBoxWriteText.java` ```java 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 文档。 ```java try (PDDocument doc = new PDDocument()) { ``` 创建一个新的`PDDocument`。 默认情况下,文档具有 A4 格式。 ```java PDPage myPage = new PDPage(); doc.addPage(myPage); ``` 创建一个新页面并将其添加到文档中。 ```java try (PDPageContentStream cont = new PDPageContentStream(doc, myPage)) { ``` 要写入 PDF 页面,我们必须创建一个`PDPageContentStream`对象。 ```java cont.beginText(); ... cont.endText(); ``` 在`beginText()`和`endText()`方法之间写入文本。 ```java cont.setFont(PDType1Font.TIMES_ROMAN, 12); cont.setLeading(14.5f); ``` 我们设置字体和文本开头。 ```java cont.newLineAtOffset(25, 700); ``` 我们使用`newLineAtOffset()`方法开始新的一行文本。 页面的原点位于左下角。 ```java String line1 = "World War II (often abbreviated to WWII or WW2), " + "also known as the Second World War,"; cont.showText(line1); ``` 文本使用`showText()`方法编写。 ```java cont.newLine(); ``` 使用`newLine()`方法,我们移至下一行文本的开头。 ## Java PDFBox 读取文本 下一个示例从 PDF 文件读取文本。 `JavaPdfBoxReadText.java` ```java 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 文档的文本及其大小。 ```java File myFile = new File("src/main/resources/wwii.pdf"); try (PDDocument doc = PDDocument.load(myFile)) { ``` 我们从`src/main/resources`目录加载 PDF 文档。 ```java PDFTextStripper stripper = new PDFTextStripper(); String text = stripper.getText(doc); ``` `PDFTextStripper`用于从 PDF 文件提取文本。 ## Java PDFBox 创建图像 下一个示例在 PDF 文档中创建图像。 `JavaPdfBoxCreateImage.java` ```java 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 文档,然后将图像添加到页面中。 ```java String imgFileName = "src/main/resources/sid2.jpg"; PDImageXObject pdImage = PDImageXObject.createFromFile(imgFileName, doc); ``` `PDImageXObject`用于处理 PDFBox 中的图像。 ```java int iw = pdImage.getWidth(); int ih = pdImage.getHeight(); ``` 我们得到图像的宽度和高度。 ```java try (PDPageContentStream cont = new PDPageContentStream(doc, myPage)) { cont.drawImage(pdImage, offset, offset, iw, ih); } ``` `PDPageContentStream`的`drawImage()`将图像绘制到页面中。 ## Java PDFBox 文档信息 PDF 文档可以包含描述文档本身或文档中某些对象(例如文档的作者或创建日期)的信息。 可以使用`PDDocumentInformation`对象设置和检索基本信息。 `JavaPdfBoxDocumentInformation.java` ```java 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 文档属性中看到。 ```java PDDocumentInformation pdi = doc.getDocumentInformation(); ``` 我们得到`PDDocumentInformation`对象。 ```java pdi.setAuthor("Jan Bodnar"); pdi.setTitle("World war II"); pdi.setCreator("Java code"); ``` 我们设置一些元数据信息。 ## Java PDFBox 编写元数据 可扩展元数据平台(XMP)是用于创建,处理和交换数字文档和数据集的标准化和自定义元数据的 ISO 标准。 PDF 文件使用 XMP 来存储其他元数据信息。 `metadata.xml` ```java <?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 文档的一些基本元数据。 `JavaPdfBoxMetadataWrite.java` ```java 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 文件读取元数据,并将其存储在生成的二进制文档中。 ```java PDMetadata meta = new PDMetadata(doc, is); ``` `PDMetadata`用于处理元数据。 ```java PDDocumentCatalog catalog = doc.getDocumentCatalog(); catalog.setMetadata(meta); ``` 我们将元数据设置为文档的目录。 ## Java PDFBox 读取元数据 在下一个示例中,我们从 PDF 文档中读取元数据。 `JavaPdfBoxMetadataRead.java` ```java 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 文档读取元数据,并将其打印到控制台。 ```java PDDocumentCatalog catalog = doc.getDocumentCatalog(); PDMetadata metadata = catalog.getMetadata(); ``` 我们从`PDDocumentCatalog`中检索`PDMetadata`。 ```java if (metadata == null) { System.err.println("No metadata in document"); System.exit(1); } ``` 该文档可能不包含元数据; 因此,我们进行一些简单的检查。 ```java 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 JFreeChart 教程](/java/jfreechart/), [Java 2D 教程](/gfx/java2d/)或 [Java 教程](/lang/java/)。