Java POI实现Excel转PDF的完整指南

一、技术背景与需求场景

在企业应用开发中,经常需要将Excel报表转换为不可编辑的PDF格式,用于归档、分发或打印。Java生态中,Apache POI是处理Microsoft Office格式文件的主流开源库,它提供了丰富的API来读写Excel(.xls/.xlsx)和Word文档。

二、核心原理与技术选型

使用POI实现Excel转PDF,其核心思路是:首先通过POI将Excel内容解析为内存中的文档对象,然后借助其他库(如iText或JFreePDF)将内容渲染为PDF。本指南推荐POI + iText组合,这是社区验证较为成熟的方案。

三、环境准备与依赖配置

项目需要引入以下Maven依赖:

<!-- Apache POI -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>
<!-- iText PDF -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.2.5</version>
    <type>pom</type>
</dependency>

四、完整代码示例

以下是一个将Excel转换为PDF的完整工具类实现:

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;

public class ExcelToPdfConverter {
    public static void convert(String excelPath, String pdfPath) throws Exception {
        try (InputStream excelStream = new FileInputStream(excelPath);
             Workbook workbook = new XSSFWorkbook(excelStream);
             OutputStream pdfStream = new FileOutputStream(pdfPath)) {
            
            // 创建PDF文档
            PdfWriter writer = new PdfWriter(pdfStream);
            PdfDocument pdfDoc = new PdfDocument(writer);
            Document document = new Document(pdfDoc);
            
            // 遍历所有Sheet
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
                Sheet sheet = workbook.getSheetAt(i);
                
                // 创建表格(根据实际行列数)
                Table table = new Table(sheet.getLastRowNum() + 1);
                table.useAllAvailableWidth();
                
                // 填充数据
                for (Row row : sheet) {
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        Cell cell = row.getCell(j, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                        String cellValue = getCellValue(cell);
                        table.addCell(new Cell().add(cellValue));
                    }
                }
                document.add(table);
                document.add(new AreaBreak(AreaBreakType.NEXT_PAGE)); // 分页
            }
            document.close();
        }
    }
    
    private static String getCellValue(Cell cell) {
        switch (cell.getCellType()) {
            case STRING: return cell.getStringCellValue();
            case NUMERIC: return String.valueOf(cell.getNumericCellValue());
            case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
            default: return "";
        }
    }
}

五、进阶优化策略

  • 样式保留:需要解析Cell的字体、颜色、边框等样式,并在创建PDF Cell时同步设置
  • 分页控制:根据纸张大小和内容长度计算分页点,避免表格被截断
  • 内存管理:处理大文件时使用SXSSFWorkbook(流式API)减少内存占用
  • 复杂合并单元格:需解析MergedRegion并应用colspan/rowspan到PDF表格

六、常见问题与解决方案

1. 中文显示异常:需为iText注册中文字体(如思源宋体)
2. 样式丢失:需完整实现样式解析逻辑,包括条件格式
3. 性能瓶颈:对10万行以上数据建议异步处理并添加进度回调

七、总结

基于POI和iText的Excel转PDF方案具有高可控性和灵活性,适合需要精细控制转换效果的企业应用。开发者可根据实际需求,在基础框架上扩展更多高级功能,如图表转换、水印添加等。