- 读取 Excel 文件:使用一个库来解析 Excel 文件,将其内容加载到内存中。
- 生成 PDF 文档:使用另一个库来创建 PDF 文档,并将 Excel 中的内容(如单元格、图片、样式等)绘制到 PDF 页面上。
下面我将为您详细介绍几种主流的实现方法,包括它们的优缺点、完整的代码示例和 Maven 依赖配置。

使用 Apache POI + iText (最灵活,但代码最复杂)
这是最传统也是最灵活的方法,Apache POI 负责读取 Excel,iText 负责生成 PDF,你需要手动遍历 Excel 的每一个单元格,并将其样式和内容“翻译”成 PDF 中的相应元素。
优点:
- 完全控制:对 PDF 的每一个像素、每一个元素都有绝对的控制权。
- 功能强大:可以实现任何复杂的 PDF 布局和样式。
缺点:
- 代码量巨大:需要自己处理 Excel 的所有复杂结构(合并单元格、样式、图片、图表等),实现起来非常繁琐。
- 维护困难:Excel 和 PDF 的映射关系复杂,代码难以维护。
适用场景:

- 需要生成高度定制化、与原始 Excel 布局完全一致的 PDF。
- 作为学习或底层库开发。
示例代码 (简化版)
这个示例仅演示了基本文本转换,省略了样式、图片等复杂处理。
Maven 依赖 (pom.xml)
<dependencies>
<!-- Apache POI for Excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- iText for PDF -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
</dependencies>
Java 代码
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class PoiToPdf {
public static void main(String[] args) {
String excelPath = "input.xlsx";
String pdfPath = "output.pdf";
try {
convertExcelToPdf(excelPath, pdfPath);
System.out.println("转换成功!PDF 已保存到: " + pdfPath);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void convertExcelToPdf(String excelPath, String pdfPath) throws IOException, DocumentException {
// 1. 加载 Excel 文件
FileInputStream excelInputStream = new FileInputStream(new File(excelPath));
Workbook workbook = new XSSFWorkbook(excelInputStream);
// 2. 创建 PDF 文档
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
document.open();
// 3. 遍历 Excel 的每一个 Sheet
for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
// 如果不是第一页,添加新页面
if (sheetIndex > 0) {
document.newPage();
}
// 创建一个表格,列数为第一行的列数
int colCount = sheet.getRow(0).getPhysicalNumberOfCells();
PdfPTable pdfTable = new PdfPTable(colCount);
// 4. 遍历 Sheet 的每一行
for (Row row : sheet) {
// 5. 遍历每一行的每一个单元格
for (Cell cell : row) {
PdfPCell pdfCell = new PdfPCell();
// 获取单元格内容
switch (cell.getCellType()) {
case STRING:
pdfCell.addElement(new Paragraph(cell.getStringCellValue()));
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
pdfCell.addElement(new Paragraph(cell.getDateCellValue().toString()));
} else {
pdfCell.addElement(new Paragraph(String.valueOf(cell.getNumericCellValue())));
}
break;
case BOOLEAN:
pdfCell.addElement(new Paragraph(String.valueOf(cell.getBooleanCellValue())));
break;
default:
pdfCell.addElement(new Paragraph(""));
}
pdfTable.addCell(pdfCell);
}
}
document.add(pdfTable);
}
// 6. 关闭资源
document.close();
workbook.close();
excelInputStream.close();
}
}
使用 Apache POI + Apache PDFBox (推荐,免费开源)
PDFBox 是 Apache 基金会的另一个优秀项目,专门用于处理 PDF,它比 iText 更现代,API 也更友好,虽然也需要手动处理,但社区和文档支持更好。

优点:
- 免费开源:无任何商业限制。
- 功能全面:支持 PDF 的创建、渲染、提取、签名等。
- 社区活跃:文档和示例相对丰富。
缺点:
- 同样需要编写大量代码来处理 Excel 到 PDF 的映射,实现复杂布局依然困难。
适用场景:
- 不想使用商业库,且希望有一个更现代、更易用的免费解决方案。
示例代码 (简化版)
Maven 依赖 (pom.xml)
<dependencies>
<!-- Apache POI for Excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- Apache PDFBox for PDF -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
</dependencies>
Java 代码
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class PoiToPdfBox {
public static void main(String[] args) {
String excelPath = "input.xlsx";
String pdfPath = "output.pdf";
try (PDDocument document = new PDDocument();
Workbook workbook = new XSSFWorkbook(new FileInputStream(excelPath))) {
// 创建一个 PDF 页面
PDPage page = new PDPage();
document.addPage(page);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
// 设置字体和字号 (这里需要自己处理字体文件,为简化省略)
// PDType0Font font = PDType0Font.load(document, new File("path/to/font.ttf"));
// contentStream.setFont(font, 12);
float yPosition = 700; // Y 坐标,PDF 坐标系原点在左下角
float margin = 50;
float leading = 15;
contentStream.beginText();
// contentStream.setFont(font, 12);
contentStream.newLineAtOffset(margin, yPosition);
contentStream.showText("Excel to PDF Conversion");
contentStream.endText();
yPosition -= leading;
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
StringBuilder rowText = new StringBuilder();
for (Cell cell : row) {
switch (cell.getCellType()) {
case STRING:
rowText.append(cell.getStringCellValue()).append("\t");
break;
case NUMERIC:
rowText.append(cell.getNumericCellValue()).append("\t");
break;
default:
rowText.append("\t");
}
}
if (rowText.length() > 0) {
contentStream.beginText();
// contentStream.setFont(font, 12);
contentStream.newLineAtOffset(margin, yPosition);
contentStream.showText(rowText.toString());
contentStream.endText();
yPosition -= leading;
}
}
}
document.save(new File(pdfPath));
System.out.println("转换成功!PDF 已保存到: " + pdfPath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用商业库 (最简单、效果最好,但需要付费)
对于绝大多数企业应用来说,使用商业库是最佳选择,这些库专门解决了 Excel 到 PDF 转换的所有难题,包括样式、布局、图片、图表等,可以做到“像素级”完美还原。
优点:
- 极其简单:通常只需要几行代码就能完成转换。
- 效果完美:能高度还原 Excel 的原始外观,包括字体、颜色、边框、合并单元格、图片等。
- 功能强大:支持多种 Excel 版本、处理复杂公式、保护工作表等。
缺点:
- 需要付费:商业库通常需要购买许可证,但对于企业来说,节省的开发时间和维护成本远超费用。
- 有免费试用版:通常提供免费试用,但会在生成的 PDF 上添加水印或限制功能。
推荐的商业库
-
Aspose.Cells for Java
-
业界标杆,功能最强大,转换效果最好,文档最完善。
-
示例代码:
import com.aspose.cells.*; import java.io.*; public class AsposeCellsExample { public static void main(String[] args) throws Exception { // 加载 Excel 文件 Workbook workbook = new Workbook("input.xlsx"); // 保存为 PDF 格式 workbook.save("output.pdf", SaveFormat.PDF); System.out.println("转换成功!"); } }Maven 依赖:
<dependency> <groupId>com.aspose</groupId> <artifactId>aspose-cells</artifactId> <version>23.8</version> <!-- 请使用最新版本 --> </dependency>
-
-
Spire.XLS for Java
-
另一个优秀的商业库,功能与 Aspose.Cells 类似,价格更具竞争力,在国内开发者中很受欢迎。
-
示例代码:
import com.spire.xls.*; import java.io.*; public class SpireXlsExample { public static void main(String[] args) { // 创建 Workbook 实例 Workbook workbook = new Workbook(); // 加载 Excel 文件 workbook.loadFromFile("input.xlsx"); // 保存为 PDF workbook.saveToFile("output.pdf", FileFormat.PDF); System.out.println("转换成功!"); } }Maven 依赖:
<dependency> <groupId>e-iceblue</groupId> <artifactId>spire.xls</artifactId> <version>13.4.0</version> <!-- 请使用最新版本 --> </dependency>
-
总结与选择建议
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| Apache POI + iText | 完全控制,免费 | 代码极其复杂,维护困难 | 学习、底层研究、需要极致定制化的项目 |
| Apache POI + PDFBox | 免费,现代API | 代码依然复杂,实现完美布局困难 | 追求免费方案,且转换要求不高的项目 |
| 商业库 (Aspose/Spire) | 代码简单,效果完美,功能强大 | 需要付费 | 绝大多数企业级应用的首选,追求开发效率和转换质量 |
给您的建议:
- 如果这是您的个人项目或学习目的,可以尝试使用 Apache POI + PDFBox,了解其底层原理。
- 如果这是您的商业项目或工作需求,强烈推荐使用商业库,如 Aspose.Cells 或 Spire.XLS,它们能为您节省数周甚至数月的开发时间,并提供稳定、高质量的转换结果,投资回报率非常高,您可以直接去它们的官网下载试用版进行体验。
