PDFBox 实战:将 Excel 文件转换为 PDF 的完整指南

引言

在当今数字化办公环境中,将 Excel 电子表格转换为 PDF 文档是一项常见需求。PDF 格式以其跨平台兼容性和固定布局特性,成为文档分发的理想选择。Apache PDFBox 作为一个强大的开源 Java 库,提供了丰富的 PDF 操作功能。虽然 PDFBox 本身不直接支持 Excel 解析,但通过与其他库(如 Apache POI)结合,我们可以构建一个完整的转换解决方案。

技术背景与准备

Apache PDFBox 是一个用于创建、渲染、打印和保存 PDF 文档的 Java 工具库。而 Apache POI 则专门用于处理 Microsoft Office 格式文件,包括 Excel。二者的结合为我们提供了从 Excel 数据提取到 PDF 生成的完整链路。

环境配置

在开始之前,请确保您的开发环境中已添加以下 Maven 依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.27</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
</dependencies>

实现步骤详解

步骤一:读取 Excel 文件

使用 Apache POI 的 XSSFWorkbook(针对 .xlsx 格式)或 HSSFWorkbook(针对 .xls 格式)类来加载 Excel 文件。以下代码示例展示了如何读取第一个工作表:

File excelFile = new File("input.xlsx");
Workbook workbook = new XSSFWorkbook(new FileInputStream(excelFile));
Sheet sheet = workbook.getSheetAt(0);

步骤二:创建 PDF 文档并准备内容

使用 PDFBox 的 PDDocument 类创建 PDF 文档,并通过 PDPageContentWriter 在页面上绘制内容:

PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
PDPageContentWriter contentWriter = new PDPageContentWriter(document, page);

步骤三:将 Excel 数据绘制到 PDF

遍历 Excel 行和单元格,使用 PDFBox 的文本绘制方法将内容写入 PDF。注意处理单元格样式、换行和字体设置:

contentWriter.beginText();
float yPosition = 700; // 初始 Y 坐标
PDType1Font font = PDType1Font.HELVETICA;

for (Row row : sheet) {
    StringBuilder line = new StringBuilder();
    for (Cell cell : row) {
        line.append(cell.toString()).append("\t");
    }
    contentWriter.setFont(font, 10);
    contentWriter.newLineAtOffset(50, yPosition);
    contentWriter.showText(line.toString());
    yPosition -= 20; // 调整下一行位置
}

contentWriter.endText();

步骤四:保存并关闭文档

完成内容绘制后,保存 PDF 文件并释放资源:

contentWriter.close();
document.save("output.pdf");
document.close();
workbook.close();

高级优化与注意事项

  • 分页处理: 当数据量超过单页容量时,需要检测并创建新页面。
  • 表格样式: 可使用 PDFBox 绘制矩形和线条来增强表格视觉效果。
  • 字体支持: 确保使用支持中文等字符的字体文件(如通过 PDType0Font 加载 TTF 字体)。
  • 性能优化: 对于大型 Excel 文件,考虑使用流式处理以减少内存占用。

完整代码示例

以下是一个封装好的转换工具类示例:

public class ExcelToPdfConverter {
    public static void convert(String excelPath, String pdfPath) throws Exception {
        // 1. 加载 Excel
        Workbook workbook = new XSSFWorkbook(new File(excelPath));
        Sheet sheet = workbook.getSheetAt(0);
        
        // 2. 创建 PDF
        PDDocument document = new PDDocument();
        PDPage page = new PDPage(PDRectangle.A4);
        document.addPage(page);
        PDPageContentWriter writer = new PDPageContentWriter(document, page);
        
        // 3. 绘制内容(此处简化,实际需处理分页和样式)
        writer.beginText();
        float y = 700;
        for (Row row : sheet) {
            StringBuilder sb = new StringBuilder();
            for (Cell cell : row) {
                sb.append(cell.toString()).append(" | ");
            }
            writer.setFont(PDType1Font.HELVETICA, 10);
            writer.newLineAtOffset(20, y);
            writer.showText(sb.toString());
            y -= 18;
            if (y < 50) { // 简单分页判断
                writer.endText();
                writer.close();
                page = new PDPage(PDRectangle.A4);
                document.addPage(page);
                writer = new PDPageContentWriter(document, page);
                writer.beginText();
                y = 700;
            }
        }
        writer.endText();
        
        // 4. 保存
        writer.close();
        document.save(pdfPath);
        document.close();
        workbook.close();
    }
}

总结与展望

通过结合 Apache PDFBox 和 Apache POI,我们实现了 Excel 到 PDF 的自动化转换。尽管过程涉及多个步骤,但该方案灵活、可定制,能满足大多数业务场景。未来,您还可以探索将此功能封装为微服务或集成到文档工作流系统中,进一步提升办公自动化水平。