杰瑞科技汇

java excel 转pdf

  1. 读取 Excel 文件:使用一个库来解析 Excel 文件,将其内容加载到内存中。
  2. 生成 PDF 文档:使用另一个库来创建 PDF 文档,并将 Excel 中的内容(如单元格、图片、样式等)绘制到 PDF 页面上。

下面我将为您详细介绍几种主流的实现方法,包括它们的优缺点、完整的代码示例和 Maven 依赖配置。

java excel 转pdf-图1
(图片来源网络,侵删)

使用 Apache POI + iText (最灵活,但代码最复杂)

这是最传统也是最灵活的方法,Apache POI 负责读取 Excel,iText 负责生成 PDF,你需要手动遍历 Excel 的每一个单元格,并将其样式和内容“翻译”成 PDF 中的相应元素。

优点:

  • 完全控制:对 PDF 的每一个像素、每一个元素都有绝对的控制权。
  • 功能强大:可以实现任何复杂的 PDF 布局和样式。

缺点:

  • 代码量巨大:需要自己处理 Excel 的所有复杂结构(合并单元格、样式、图片、图表等),实现起来非常繁琐。
  • 维护困难:Excel 和 PDF 的映射关系复杂,代码难以维护。

适用场景:

java excel 转pdf-图2
(图片来源网络,侵删)
  • 需要生成高度定制化、与原始 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 也更友好,虽然也需要手动处理,但社区和文档支持更好。

java excel 转pdf-图3
(图片来源网络,侵删)

优点:

  • 免费开源:无任何商业限制。
  • 功能全面:支持 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 上添加水印或限制功能。

推荐的商业库

  1. 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>
  2. 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.CellsSpire.XLS,它们能为您节省数周甚至数月的开发时间,并提供稳定、高质量的转换结果,投资回报率非常高,您可以直接去它们的官网下载试用版进行体验。
分享:
扫描分享到社交APP
上一篇
下一篇