Java PDFBox

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 文档并在其中写入一些文本。

JavaPdfBoxWriteText.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 文档。

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

文字写在beginTextendText方法之间。

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 文件中读取文本。

JavaPdfBoxReadText.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 文档的文本及其大小。

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 文档中创建图像。

JavaPdfBoxCreateImage.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 文档,并将图像添加到页面中。

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's drawImage将图像绘制到页面中。

Java PDFBox 文档信息

PDF 文档可以包含描述文档本身或文档中某些对象的信息,例如文档的作者或其创建日期。可以使用该PDDocumentInformation对象设置和检索基本信息。

JavaPdfBoxDocumentInformation.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 文档属性中查看该信息。

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
<?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
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 文档中读取元数据。

JavaPdfBoxMetadataRead.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 文档中读取元数据并将其打印到控制台。

PDDocumentCatalog catalog = doc.getDocumentCatalog();
PDMetadata metadata = catalog.getMetadata();

我们PDMetadataPDDocumentCatalog.

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 文件。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值