杰瑞科技汇

Java如何实现HTML转Excel?

下面我将为你详细介绍几种主流的实现方法,从最简单到最灵活,并附上完整的代码示例。

核心思路

无论使用哪种库,基本流程都是相似的:

  1. 准备 HTML 字符串:确保你的 HTML 是一个结构良好的 <table>
  2. 创建 Excel 工作簿 (Workbook):这是 Excel 文件在内存中的表示。
  3. 创建工作表 (Sheet):一个工作簿可以包含多个工作表。
  4. 解析 HTML <table>:逐行、逐单元格地读取 HTML 数据。
  5. 写入 Excel 单元格 (Cell):将解析出的数据填充到工作表的对应位置。
  6. 设置样式(可选):如字体、颜色、边框等,使 Excel 更美观。
  7. 输出文件:将内存中的 Workbook 写入到 .xlsx.xls 文件中。

使用 Apache POI (最常用、最灵活)

Apache POI 是 Java 操作 Office 文件(如 Word, Excel)的事实标准,它功能强大,但 API 相对繁琐,我们通常会用一个辅助库来简化 HTML 的解析。

步骤 1: 添加 Maven 依赖

你需要 poipoi-ooxml (用于 .xlsx 格式),以及一个 HTML 解析器,这里推荐 jsoup

<dependencies>
    <!-- Apache POI 核心库 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.3</version>
    </dependency>
    <!-- Apache POI for .xlsx format -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
    <!-- Jsoup: 用于解析 HTML -->
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.15.3</version>
    </dependency>
</dependencies>

步骤 2: Java 代码实现

jsoup 可以非常方便地解析 HTML,并让我们通过 CSS 选择器来定位 <table>, <tr>, <td> 等元素。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.IOException;
public class HtmlToExcelWithPOI {
    public static void main(String[] args) {
        // 1. 准备 HTML 字符串 (这里是一个包含样式的示例)
        String html = "<table border='1'>" +
                "<thead>" +
                "<tr><th style='background-color: #AAAAAA;'>姓名</th><th style='background-color: #AAAAAA;'>年龄</th><th style='background-color: #AAAAAA;'>城市</th></tr>" +
                "</thead>" +
                "<tbody>" +
                "<tr><td>张三</td><td>28</td><td>北京</td></tr>" +
                "<tr><td>李四</td><td>32</td><td>上海</td></tr>" +
                "<tr><td>王五</td><td>45</td><td>广州</td></tr>" +
                "</tbody>" +
                "</table>";
        // 2. 创建 Excel 工作簿 (.xlsx)
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("数据表");
            // 3. 使用 Jsoup 解析 HTML
            Document doc = Jsoup.parse(html);
            Element table = doc.select("table").first(); // 获取第一个 table 元素
            if (table == null) {
                System.out.println("HTML 中未找到 table 标签");
                return;
            }
            Elements rows = table.select("tr"); // 获取所有行
            int rowNum = 0;
            // 4. 遍历每一行
            for (Element row : rows) {
                Row excelRow = sheet.createRow(rowNum++);
                Elements cells = row.select("td, th"); // 获取该行的所有单元格 (td 或 th)
                int colNum = 0;
                // 5. 遍历每一个单元格
                for (Element cell : cells) {
                    Cell excelCell = excelRow.createCell(colNum++);
                    // 设置单元格值
                    excelCell.setCellValue(cell.text());
                    // 6. (可选) 应用样式
                    // 这里我们简单地将表头加粗
                    if (cell.tagName().equals("th")) {
                        CellStyle headerStyle = workbook.createCellStyle();
                        Font headerFont = workbook.createFont();
                        headerFont.setBold(true);
                        headerStyle.setFont(headerFont);
                        // 设置背景色 (需要使用 XSSF 的 PatternFill)
                        if (workbook instanceof XSSFWorkbook) {
                            ((XSSFWorkbook) workbook).getStylesSource().putCellStyle("header", headerStyle);
                            // 注意:POI 对内联样式的支持有限,这里只是演示如何设置基础样式
                            // 复杂的 HTML 样式(如 background-color)需要更复杂的解析
                        }
                        excelCell.setCellStyle(headerStyle);
                    }
                }
            }
            // 自动调整列宽
            for (int i = 0; i < sheet.getRow(0).getPhysicalNumberOfCells(); i++) {
                sheet.autoSizeColumn(i);
            }
            // 7. 写入文件
            try (FileOutputStream fileOut = new FileOutputStream("output_with_poi.xlsx")) {
                workbook.write(fileOut);
                System.out.println("Excel 文件已成功生成: output_with_poi.xlsx");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

优点

  • 功能最强大:可以完全控制 Excel 的每一个细节,包括复杂的样式、公式、图表等。
  • 社区活跃:遇到问题很容易找到解决方案。
  • 稳定可靠:经过长期验证,是业界标准。

缺点

  • API 繁琐:对于简单的转换,代码量相对较多。
  • 样式处理复杂:直接解析 HTML 的内联样式(如 style="background-color: #ff0000;")比较麻烦,需要自己编写解析逻辑。

使用 EasyExcel (阿里巴巴,推荐)

EasyExcel 是阿里巴巴开源的一个处理 Excel 的项目,它以简单、节省内存著称,它本身不直接支持 HTML 转 Excel,但我们可以结合 jsoup 来读取数据,然后利用 EasyExcel 优雅的 API 来写入。

步骤 1: 添加 Maven 依赖

<dependencies>
    <!-- EasyExcel 核心库 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.1.1</version>
    </dependency>
    <!-- Jsoup: 用于解析 HTML (同上) -->
    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.15.3</version>
    </dependency>
</dependencies>

步骤 2: Java 代码实现

EasyExcel 的核心是 ExcelWriterWriteSheet,我们可以将 HTML 表格的数据转换成一个 List<List<String>> 的结构,这正是 EasyExcel 所期望的。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class HtmlToExcelWithEasyExcel {
    public static void main(String[] args) {
        String html = "<table>" +
                "<tr><th>姓名</th><th>年龄</th><th>城市</th></tr>" +
                "<tr><td>赵六</td><td>25</td><td>深圳</td></tr>" +
                "<tr><td>孙七</td><td>38</td><td>杭州</td></tr>" +
                "</table>";
        // 1. 使用 Jsoup 解析 HTML 并转换为 List<List<String>>
        List<List<String>> data = parseHtmlToDataList(html);
        if (data == null || data.isEmpty()) {
            System.out.println("数据为空,无法生成 Excel");
            return;
        }
        // 2. 创建 Excel 文件输出流
        String fileName = "output_with_easyexcel.xlsx";
        try (FileOutputStream fos = new FileOutputStream(fileName)) {
            // 3. 创建 ExcelWriter
            ExcelWriter excelWriter = EasyExcel.write(fos).build();
            // 4. 创建 WriteSheet
            WriteSheet writeSheet = EasyExcel.writerSheet("用户数据").build();
            // 5. 写入数据
            excelWriter.write(data, writeSheet);
            // 6. 关闭 ExcelWriter (会自动关闭流)
            excelWriter.finish();
            System.out.println("Excel 文件已成功生成: " + fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 将 HTML table 解析为 List<List<String>>
     * @param html 包含 table 的 HTML 字符串
     * @return 数据列表
     */
    private static List<List<String>> parseHtmlToDataList(String html) {
        List<List<String>> dataList = new ArrayList<>();
        Document doc = Jsoup.parse(html);
        Element table = doc.select("table").first();
        if (table == null) {
            return dataList;
        }
        Elements rows = table.select("tr");
        for (Element row : rows) {
            List<String> cellDataList = new ArrayList<>();
            Elements cells = row.select("td, th");
            for (Element cell : cells) {
                cellDataList.add(cell.text());
            }
            dataList.add(cellDataList);
        }
        return dataList;
    }
}

优点

  • API 极其简洁:代码量少,可读性高,上手快。
  • 性能优秀:特别是处理大文件时,其“模型写入”和“监听器”模式能极大地节省内存。
  • 功能强大:支持注解、动态头、自定义转换器等高级功能。

缺点

  • 生态相对 POI 较小:虽然已经很流行,但社区和资料相比 POI 还有一定差距。
  • 样式控制能力不如 POI:EasyExcel 更侧重于数据读写,对于复杂样式的支持不如 POI 灵活。

使用第三方转换库 (如 Aspose.Cells)

Aspose.Cells 是一个商业的 Java 组件,以其功能全面、性能卓越和完美的格式兼容性而闻名,它提供了一种非常直接的方式来实现 HTML 转 Excel。

步骤 1: 添加 Maven 依赖 (需要商业许可)

<dependencies>
    <!-- Aspose.Cells -->
    <dependency>
        <groupId>com.aspose</groupId>
        <artifactId>aspose-cells</artifactId>
        <version>23.8</version>
        <!-- scope 需要设置为 compile 或 provided,并且需要有效的 license -->
    </dependency>
</dependencies>

注意:Aspose.Cells 是商业软件,需要购买许可证才能在产品环境中使用,它有一个免费的评价版本,但会有一些限制。

步骤 2: Java 代码实现

Aspose.Cells 提供了 com.aspose.cells.Workbook 类,其 importHtml() 方法可以直接从字符串或文件导入 HTML。

import com.aspose.cells.*;
public class HtmlToExcelWithAspose {
    public static void main(String[] args) throws Exception {
        // 1. 准备 HTML 字符串
        String html = "<table><tr><th>产品</th><th>价格</th></tr><tr><td>苹果</td><td>5.5</td></tr><tr><td>香蕉</td><td>3.2</td></tr></table>";
        // 2. 创建一个 Workbook 对象
        Workbook workbook = new Workbook();
        // 3. 获取第一个工作表
        Worksheet sheet = workbook.getWorksheets().get(0);
        // 4. 使用 ImportHtml 方法直接导入 HTML
        // 参数1: HTML 字符串
        // 参数2: 导入内容类型 (HtmlImportType.TABLE)
        // 参数3: 目标行索引 (从0开始)
        // 参数4: 目标列索引 (从0开始)
        sheet.getCells().importHtml(html, HtmlImportType.TABLE, 0, 0);
        // 5. (可选) 自动调整列宽
        sheet.autoFitColumns();
        // 6. 保存 Excel 文件
        workbook.save("output_with_aspose.xlsx");
        System.out.println("Excel 文件已成功生成: output_with_aspose.xlsx");
    }
}

优点

  • 代码最简单:一行代码 importHtml() 搞定所有事情,包括解析和基本样式。
  • 兼容性最好:能最大程度地保留原始 HTML 的样式和布局。
  • 性能卓越:处理大型文件时表现出色。

缺点

  • 收费:这是最大的门槛,不适合个人项目或预算有限的公司。
  • 闭源:无法像 POI 那样深入源码进行定制。

总结与如何选择

特性 Apache POI + Jsoup EasyExcel + Jsoup Aspose.Cells
易用性 中等 极高
功能/灵活性 极高 高 (数据) / 中等 (样式) 极高
性能 良好 优秀 (尤其大文件) 优秀
成本 免费 (开源) 免费 (开源) 收费 (商业)
样式支持 需手动实现,复杂 较弱 优秀 (自动保留)
适用场景 需要精细控制 Excel,或已有 POI 技术栈 日常开发、大数据量写入、追求简洁代码 预算充足,追求最高效、最简单的转换,且需要完美保留样式

给你的建议:

  • 如果你是初学者,或者项目追求快速开发、代码简洁:强烈推荐 EasyExcel + Jsoup,它在易用性和性能之间取得了很好的平衡。
  • 如果你的项目对 Excel 的样式、格式有极高的要求,或者你已经在使用 POI:选择 Apache POI + Jsoup,虽然代码多一点,但控制力最强。
  • 如果你的公司预算充足,并且希望用最少的代码实现最完美的转换:可以考虑 Aspose.Cells,它的 importHtml() 方法确实非常方便。
分享:
扫描分享到社交APP
上一篇
下一篇