找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3352

积分

0

好友

442

主题
发表于 昨天 23:35 | 查看: 2| 回复: 0

一年三连跳:EasyExcel → FastExcel → Apache Fesod

Java 圈最常用的 Excel 库,过去一年完成了一次罕见的「三连跳」:

  • 2024 年底:阿里官宣 EasyExcel 不再维护 —— 5 年的头牌库进入「祝它好运」状态;
  • 2024-2025:原作者离开阿里后推出 FastExcel —— API 完全兼容,主打「换 import 就能切」;
  • 2025-2026:FastExcel 再次"消失" —— 原作者把项目整套捐给了 Apache 软件基金会,更名为 Apache Fesod (Incubating)。最新版本 2.0.1-incubating 已于 2026-02-11 发布。

Java Excel 处理演进:内存、吞吐与错误定位是关键

不少人可能懵了:「上次刚改完 import,怎么又换名字了?」

别紧张:这次不是停更,是升级到 Apache 一级开源项目 —— 代码所有权从个人/公司转给基金会,长期维护、版本节奏跟 Apache POI、Maven、Tomcat 一个待遇。这是开源项目能拿到的最好结局。

说白了:它不是「比 FastExcel 更强的另一个轮子」,是「FastExcel 拿到了 Apache 终身保障」 —— 对存量项目,这是迁移成本最低、最值得切换的接班选项。

横向对比:5 个 Excel 处理方案怎么选

把过去 5 年常见的 5 个方案放一张表,差距一目了然:

方案 维护状态 适用规模 内存模型 致命短板
Apache POI 活跃 任意 DOM(重) 十万行级写入容易 OOM
POI SXSSF 活跃 大文件 流式 写还行,读不擅长
HuTool ExcelReader / Writer 活跃 < 1 万行 简单 高级特性(合并/公式)受限
EasyExcel 2024 年起阿里停更 任意 流式 不再有新功能/bug 修复
FastExcel 2025 年捐给 Apache、更名 Fesod 任意 流式 已是过渡命名,新项目别用
Apache Fesod (本文) Apache 孵化中,长期保障 任意 流式 仍在 Incubating 阶段,2.x API 微调

判断很简单

  • 新项目直接 Apache Fesod,少一次后续迁移;
  • 现有 EasyExcel / FastExcel 项目 → 切 Fesod,三步走(换坐标 + 改 import + 换入口类,详见「迁移指南」);
  • 极简场景(几行 Excel) → HuTool 一行调用即可,别上重武器;
  • 要做 Excel 转 PDF → Fesod 内置该能力,省得自己拼 itext。

3 个研发场景:什么时候它顶用

场景 1:百万行报表导出

财务、风控、运营部门要导出数十万到百万级订单数据。直接用 POI 一定 OOM —— 内存里塞百万 row 对象毕竟撑不住。

@GetMapping("/export/orders")
public void exportOrders(HttpServletResponse resp) throws IOException {
    resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    String name = URLEncoder.encode("orders", "UTF-8");
    resp.setHeader("Content-disposition", "attachment;filename*=utf-8''" + name + ".xlsx");

    // 流式写入——分页查 DB 边读边写
    try (ExcelWriter writer = FesodSheet.write(resp.getOutputStream(), Order.class).build()) {
        WriteSheet sheet = FesodSheet.writerSheet("订单").build();
        int page = 0, pageSize = 5000;
        while (true) {
            List<Order> data = orderMapper.pageQuery(page++, pageSize);
            if (data.isEmpty()) break;
            writer.write(data, sheet);
        }
    }
}

收益:流式写 + 分页查 DB(每批 5000 条),百万行导出内存稳定在 100MB 量级。

场景 2:用户上传 Excel 批量数据

客户给的 Excel 一上传动不动就上万行,逐行 INSERT DB 慢、一次性 readAll 又 OOM。Fesod 的事件监听器正是为此设计:

public class OrderBatchListener extends AnalysisEventListener<OrderRow> {
    private final List<OrderRow> buffer = new ArrayList<>();
    private static final int BATCH_SIZE = 500;
    private final OrderMapper mapper;

    public OrderBatchListener(OrderMapper mapper) { this.mapper = mapper; }

    @Override
    public void invoke(OrderRow row, AnalysisContext ctx) {
        buffer.add(row);
        if (buffer.size() >= BATCH_SIZE) {
            mapper.batchInsert(buffer);
            buffer.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext ctx) {
        if (!buffer.isEmpty()) mapper.batchInsert(buffer);
    }
}

关键设计:500 条凑一批 batchInsert —— 既不让 buffer 撑爆内存,又能利用批插提速。

场景 3:Excel 转 PDF(合同/工资单)

工资单、合同模板的常见诉求:导出的 Excel 同时给个 PDF 版方便归档/打印

FesodSheet.convertToPdf(new File("excelFile.xlsx"), new File("pdfFile.pdf"), null, null);

底层依赖 Apache POI + itext-pdf —— itext 商业用途需注意 AGPL 许可,企业项目要么走 itext 商业 license,要么换 OpenPDF。

接入 3 步:依赖 + 实体类 + 监听器

第 1 步:Maven 依赖(注意是 Apache 新坐标)

<dependency>
    <groupId>org.apache.fesod</groupId>
    <artifactId>fesod-sheet</artifactId>
    <version>2.0.1-incubating</version>
</dependency>

重点groupIdorg.apache.fesod —— 和 EasyExcel 的 com.alibaba.excel、FastExcel 的 cn.idev.excel 都不同。新项目直接用 Apache 坐标,少一次后续迁移

第 2 步:实体类(@ExcelProperty 注解列名)

import org.apache.fesod.sheet.annotation.ExcelProperty;

@Setter @Getter @ToString
public class User {
    @ExcelProperty("编号") private Integer id;
    @ExcelProperty("名字") private String name;
    @ExcelProperty("年龄") private Integer age;
}

第 3 步:事件监听器(流式处理是真活)

public class BaseExcelListener<T> extends AnalysisEventListener<T> {
    private final List<T> dataList = new ArrayList<>();

    @Override
    public void invoke(T t, AnalysisContext ctx) { dataList.add(t); }

    @Override
    public void doAfterAllAnalysed(AnalysisContext ctx) {
        log.info("读取完成,共 {} 条", dataList.size());
    }

    public List<T> getDataList() { return dataList; }
}

注意:监听器决定了内存模型。生产用法应该在 invoke 里累积 + 批量落库,而不是无脑 dataList.add —— 否则上百万行直接 OOM。

核心 API:写、读、转 PDF

FesodSheet.write(response.getOutputStream(), User.class)
    .sheet("模板")
    .doWrite(buildData());

FesodSheet.read(file.getInputStream(), User.class, listener)
    .sheet()
    .doRead();

Spring Boot 上传 + 处理

@PostMapping("/upload")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file) {
    if (file.isEmpty()) return ResponseEntity.badRequest().body("请选择文件");
    try {
        BaseExcelListener<User> listener = new BaseExcelListener<>();
        FesodSheet.read(file.getInputStream(), User.class, listener).sheet().doRead();
        log.info("上传 {} 条", listener.getDataList().size());
        return ResponseEntity.ok("处理成功");
    } catch (IOException e) {
        return ResponseEntity.status(500).body("文件处理失败");
    }
}

迁移指南:从 EasyExcel / FastExcel 切到 Fesod

Apache Fesod 官方建议分阶段迁移 —— 先换坐标 + import,再换类名,每步都跑测试,降低风险。一张表对照三代变化:

项目 EasyExcel(阿里) FastExcel(过渡) Apache Fesod(最新)
groupId com.alibaba cn.idev.excel org.apache.fesod
artifactId easyexcel fastexcel fesod-sheet
版本 3.x(停更) 1.x 2.0.1-incubating
import 包 com.alibaba.excel.* cn.idev.excel.* *`org.apache.fesod.sheet.`**
入口类 EasyExcel FastExcel FesodSheet(推荐)

迁移步骤

  1. 改 pom:换 groupId / artifactId / version
  2. 全局替换 import:IDE 一次性 cn.idev.excelorg.apache.fesod.sheet(或 com.alibaba.excel → 同上);
  3. 替换入口类FastExcel.read/writeFesodSheet.read/write
  4. 跑回归测试:流式写、监听器读、合并单元格、多 sheet 全过一遍。

API 完全兼容 —— 上层调用方式(@ExcelProperty 注解、AnalysisEventListener 监听器、ExcelWriter 写入器)一行不动。

4 个真实使用边界

边界 1:仍在 Incubating 阶段,API 微调可能(最常见)

2.0.1-incubating 是孵化器版本 —— Apache 孵化项目惯例是 API 还可能有小幅调整修法:① pom 锁死具体版本号;② 关注 fesod.apache.org 的 release notes;③ 升级前在测试环境跑全套回归。

边界 2:监听器不要把数据全留在内存(常见)

新人最容易写错的代码:

// ❌ 上百万行直接 OOM
public void invoke(T t, AnalysisContext ctx) { dataList.add(t); }

修法:累积到 batch 阈值后立刻 flush(DB/队列/文件),buffer 清空再继续。

边界 3:Excel 转 PDF 的 itext 许可(少见但破坏力大)

iText 7+ 是 AGPL 许可 —— 商用项目不买商业 license 不允许闭源。要避坑可以换 OpenPDF(LGPL)或 Aspose.PDF(商业)。法务环节别忽略

边界 4:和 FastExcel 1.x 二进制不兼容(高级场景)

虽然 API 兼容,但 FastExcel 1.x 和 Fesod 2.x 在 Maven 依赖树上是两个不同 artifact —— 同一项目两个都引会出现类冲突。迁移时必须一刀切:删掉 cn.idev.excel:fastexcel,只留 org.apache.fesod:fesod-sheet

我的判断

EasyExcel → FastExcel → Apache Fesod 的三连跳,看着折腾,但走到 Apache 这一步意味着这个工具终于有了一个不会再"消失"的家 —— 基金会保 license、社区保维护、长期 roadmap 由社区共治,不再受单家公司/单个作者影响。好的开源接班不是另起炉灶,是把已有的轮子继续往前转——这次干脆转进了 Apache,连维护权都不用再担心

仓库:github.com/apache/fesod | 官网:fesod.apache.org | 迁移指南:fesod.apache.org/docs/migration/from-fastexcel/

Excel 导入导出核心要点:关注内存、模板与工具生态升级




上一篇:AerynOS 深度测评:原子更新机制与安装实操全解
下一篇:小米Miclaw输入法被曝硬编码明文API密钥,调用豆包大模型引安全争议
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-5-3 01:47 , Processed in 0.976842 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表