使用 iText 和 Apache PDFBox 在 Java 中生成 PDF 报告

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java 中生成 PDF 报告:iText 和 Apache PDFBox 库概述

创建 PDF 文档是企业 Java 应用程序中的常见任务之一。报告、账单、发票、证书——所有这些都可以通过编程方便地生成。在 Java 生态系统中,有两个主要的 PDF 处理库:iText(行业标准,但新版本需要商业许可证)和 Apache PDFBox(完全免费且开源)。本文将介绍这两个库,展示代码示例,并帮助您为项目选择合适的工具。



1. Apache PDFBox — 功能广泛的免费替代方案

Apache PDFBox 是一个开源库(Apache 2.0 许可证)。它允许从零开始创建 PDF、编辑现有 PDF、提取文本和元数据。PDFBox 不需要商业许可证,使其成为初创公司和开源项目的理想选择。

主要功能:

  • 创建包含文本、图像和表格的文档。
  • 字体处理(包括西里尔字母)。
  • 添加书签、超链接和水印。
  • 加密和密码保护。
  • 从现有 PDF 中提取文本和图像。


示例:创建带表格的简单 PDF 报告

import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.pdmodel.PDPage;import org.apache.pdfbox.pdmodel.PDPageContentStream;import org.apache.pdfbox.pdmodel.font.PDType0Font;import org.apache.pdfbox.pdmodel.common.PDRectangle;import java.io.File;import java.io.IOException;

public class PdfBoxReport { public static void main(String[] args) throws IOException { try (PDDocument document = new PDDocument()) { PDPage page = new PDPage(PDRectangle.A4); document.addPage(page);

// 加载支持西里尔字母的字体 PDType0Font font = PDType0Font.load(document, new File("fonts/arial.ttf"));

try (PDPageContentStream cs = new PDPageContentStream(document, page)) { // 标题 cs.beginText(); cs.setFont(font, 18); cs.newLineAtOffset(50, 750); cs.showText("2025 年第一季度销售报告"); cs.endText();

// 表格(通过线条和文本的简单实现) cs.setFont(font, 12); // 绘制列标题 float margin = 50; float yStart = 700; float tableWidth = 500; float rowHeight = 25; String[] headers = {"商品", "数量", "价格,卢布"}; String[][] data = {{"笔记本电脑", "10", "85000"}, {"鼠标", "50", "1500"}, {"键盘", "30", "3500"}};

// 表格标题 cs.setLineWidth(1f); for (int i = 0; i < headers.length; i++) { cs.addRect(margin + i * (tableWidth / 3), yStart - rowHeight, tableWidth / 3, rowHeight); cs.stroke(); cs.beginText(); cs.newLineAtOffset(margin + i * (tableWidth / 3) + 5, yStart - rowHeight + 5); cs.showText(headers[i]); cs.endText(); }

// 数据 float yPos = yStart - rowHeight; for (String[] row : data) { yPos -= rowHeight; for (int i = 0; i < row.length; i++) { cs.addRect(margin + i * (tableWidth / 3), yPos, tableWidth / 3, rowHeight); cs.stroke(); cs.beginText(); cs.newLineAtOffset(margin + i * (tableWidth / 3) + 5, yPos + 5); cs.showText(row[i]); cs.endText();

推荐