Java 实现 PDF 模板动态赋值与文档生成(多种解)

476 阅读2分钟

除了 iText 库,在 Java 中还有其他一些库可以用于处理 PDF 模板并进行动态赋值,下面为你介绍几种常见的库及其使用示例。

1. Apache PDFBox

Apache PDFBox 是一个开源的 Java 库,可用于创建、操作和提取 PDF 文档中的内容。它提供了丰富的 API 来处理 PDF 表单,能够实现从 PDF 模板生成新文档并动态赋值的功能。

添加依赖

如果你使用 Maven 项目,在 ​​pom.xml​​ 中添加以下依赖:

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>3.0.0</version>
</dependency>

示例代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class PdfBoxTemplateGenerator {

    public static void main(String[] args) {
        String templatePath = "template.pdf";
        String outputPath = "output.pdf";
        Map<String, String> values = new HashMap<>();
        values.put("name", "李四");
        values.put("age", "30");

        try {
            generatePdfFromTemplate(templatePath, outputPath, values);
            System.out.println("PDF 文档生成成功,路径为: " + outputPath);
        } catch (IOException e) {
            System.err.println("生成 PDF 文档时出现错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void generatePdfFromTemplate(String templatePath, String outputPath, Map<String, String> values) throws IOException {
        // 加载 PDF 模板文档
        try (PDDocument document = PDDocument.load(new File(templatePath))) {
            // 获取文档中的表单
            PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
            if (acroForm != null) {
                // 遍历动态赋值的键值对
                for (Map.Entry<String, String> entry : values.entrySet()) {
                    // 获取表单字段
                    PDField field = acroForm.getField(entry.getKey());
                    if (field != null) {
                        // 设置字段的值
                        field.setValue(entry.getValue());
                    }
                }
            }

            // 保存修改后的文档
            document.save(outputPath);
        }
    }
}

代码解释

  • ​PDDocument.load​​:用于加载 PDF 模板文件。

  • ​document.getDocumentCatalog().getAcroForm()​​:获取 PDF 文档中的表单。

  • ​acroForm.getField​​:通过字段名称获取表单字段。

  • ​field.setValue​​:设置表单字段的值。

  • ​document.save​​:保存修改后的文档。

2. Flying Saucer

Flying Saucer 是一个用于将 HTML/CSS 转换为 PDF 的 Java 库。你可以先创建 HTML 模板,然后将其转换为 PDF 文档,并在 HTML 中使用占位符进行动态赋值。

添加依赖

如果你使用 Maven 项目,在 ​​pom.xml​​ 中添加以下依赖:

<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>flying-saucer-pdf-itext5</artifactId>
    <version>9.1.22</version>
</dependency>

示例代码

import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class FlyingSaucerTemplateGenerator {

    public static void main(String[] args) {
        String templatePath = "template.html";
        String outputPath = "output.pdf";
        Map<String, String> values = new HashMap<>();
        values.put("${name}", "王五");
        values.put("${age}", "35");

        try {
            generatePdfFromTemplate(templatePath, outputPath, values);
            System.out.println("PDF 文档生成成功,路径为: " + outputPath);
        } catch (Exception e) {
            System.err.println("生成 PDF 文档时出现错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void generatePdfFromTemplate(String templatePath, String outputPath, Map<String, String> values) throws Exception {
        // 读取 HTML 模板文件内容
        String htmlContent = new String(Files.readAllBytes(Paths.get(templatePath)));

        // 替换 HTML 中的占位符
        for (Map.Entry<String, String> entry : values.entrySet()) {
            htmlContent = htmlContent.replace(entry.getKey(), entry.getValue());
        }

        // 创建输出流
        try (OutputStream outputStream = new FileOutputStream(new File(outputPath))) {
            // 创建 ITextRenderer 对象
            ITextRenderer renderer = new ITextRenderer();
            // 设置 HTML 内容
            renderer.setDocumentFromString(htmlContent);
            // 布局渲染
            renderer.layout();
            // 生成 PDF
            renderer.createPDF(outputStream);
        }
    }
}

代码解释

  • ​Files.readAllBytes​​:读取 HTML 模板文件的内容。

  • ​htmlContent.replace​​:替换 HTML 中的占位符。

  • ​ITextRenderer.setDocumentFromString​​:设置 HTML 内容。

  • ​renderer.layout​​:进行布局渲染。

  • ​renderer.createPDF​​:生成 PDF 文档。

各库的优缺点比较

库名称优点缺点
iText功能强大,支持复杂的 PDF 操作,有丰富的文档和社区支持部分高级功能需要付费许可证
Apache PDFBox开源免费,易于使用,适合处理简单的 PDF 表单对于复杂的 PDF 布局处理能力相对较弱
Flying Saucer可以利用 HTML/CSS 的优势进行模板设计,灵活性高性能相对较低,对于复杂的 PDF 效果实现可能有一定难度