- 后端
【免费下载链接】fesod
Fast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.
本篇技术指南以 Fesod Sheet 的快速入门示例为核心,演示如何用一行式门面 APIFesodSheet完成最常见的两个场景:把 xlsx 文件按行读进 Java 对象、把 Java 对象列表写出为带表头的电子表格。读完本文,你将掌握读取监听器(ReadListener)的基本用法、@ExcelProperty/@ExcelIgnore注解的列映射规则,以及读写构建器链的底层调用关系,可以直接在业务代码中落地最小可用的导入导出功能。
文中所有示例均取自仓库内官方文档 example.md,并辅以对应源码与测试进行佐证。
环境准备
在运行示例前,需要先引入fesod-sheet依赖。当前仓库中 Apache Fesod(Incubating)官方文档(guide.md)给出的 Maven 配置为:
<dependency> <groupId>org.apache.fesod</groupId> <artifactId>fesod-sheet</artifactId> <version>2.0.2-incubating</version> </dependency>Gradle 项目则使用:
dependencies { implementation 'org.apache.fesod:fesod-sheet:2.0.2-incubating' }需要说明的适用前提:fesod-sheet依赖 Apache POI 5.5.1(Excel 处理)、Apache Commons CSV 1.14.1(CSV 支持)与 Ehcache 3.9.11(缓存)等核心组件,如果你的项目已经自带 POI 相关 jar 包,可能需要手动排除以避免版本冲突。官方文档同时列出了各版本对 JDK 的支持范围,2.0.x 系列支持 JDK 8 至 JDK 25。
读取电子表格:监听器模式一行触发
原文档给出的读取示例非常简洁,完整代码如下:
// 实现 ReadListener 接口,设置读取数据的操作 public class DemoDataListener implements ReadListener<DemoData> { @Override public void invoke(DemoData data, AnalysisContext context) { System.out.println("解析到一条数据" + JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { System.out.println("所有数据解析完成!"); } } public static void main(String[] args) { String fileName = "demo.xlsx"; // 读取文件 FesodSheet.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead(); }这段代码的调用链可以拆解为三步:
FesodSheet.read(fileName, DemoData.class, new DemoDataListener()):指定文件路径、目标 POJO 类型和监听器;.sheet():读取默认工作表(从第 0 个 sheet 开始);.doRead():真正开始逐行解析。
从源码看 read 的三种数据源
查看门面类 FesodSheet.java 可以发现,read不止接受文件路径,还针对不同数据来源提供了多种重载:
read(String pathName, Class head, ReadListener readListener):按路径读取,内部转为new File(pathName);read(File file, Class head, ReadListener readListener):直接读取文件对象;read(InputStream inputStream, Class head, ReadListener readListener):从输入流读取,适用于上传接口、网络下载等场景。
三者最终都会进入new ExcelReaderBuilder().file(...).headIfNotNull(head).registerReadListenerIfNotNull(readListener),构建出一个 ExcelReaderBuilder。也就是说,数据源(路径 / 文件 / 流)与解析逻辑是解耦的,换一种输入方式只需要改read的第一个参数。此外,如果file与inputStream同时设置,源码注释明确说明以文件优先。
ReadListener 的核心回调
读取过程中的一切行为都由 ReadListener 驱动,这是一个泛型接口ReadListener<T>,其中T是每行数据映射到的类型。它的方法分两类:
| 方法 | 触发时机 | 是否必须实现 |
|---|---|---|
invoke(T data, AnalysisContext context) | 每解析完一行数据时调用一次,data即当前行映射出的对象 | 必须 |
doAfterAllAnalysed(AnalysisContext context) | 整个文件解析完成后调用,适合做汇总、收尾或释放资源 | 必须 |
invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) | 解析表头行时触发 | 可选(默认空实现) |
onException(Exception exception, AnalysisContext context) | 任意监听器上报错误时触发,若此处抛出异常则终止整个读取 | 可选(默认抛出原异常) |
extra(CellExtra extra, AnalysisContext context) | 返回批注、超链接等额外信息时触发 | 可选(默认空实现) |
hasNext(AnalysisContext context) | 判断是否还有下一条数据,返回false可提前停止读取 | 可选(默认按numRows限制判断) |
从默认实现看,hasNext会读取当前 sheet 或整个 workbook 上配置的numRows行数上限,当已读取行数达到上限时返回false终止解析——这正是控制"只读前 N 行"能力的底层机制,对应FesodSheet.readSheet(sheetNo, sheetName, numRows)中的numRows参数。
监听器的使用注意
ReadListener需要每次读取时重新实例化,官方文档(简单读取)特别提示:监听器不宜被 Spring 容器管理并复用,因为一次读取的生命周期内监听器内部状态(如累计计数)是读取逻辑的一部分。
写入电子表格:注解驱动的一行式导出
原文档给出的写入示例同样简洁,包含数据模型、数据准备和入口三部分:
// 示例数据类 public class DemoData { @ExcelProperty("字符串标题") private String string; @ExcelProperty("日期标题") private Date date; @ExcelProperty("数字标题") private Double doubleData; @ExcelIgnore private String ignore; } // 填充要写入的数据 private static List<DemoData> data() { List<DemoData> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { DemoData data = new DemoData(); data.setString("字符串" + i); data.setDate(new Date()); data.setDoubleData(0.56); list.add(data); } return list; } public static void main(String[] args) { String fileName = "demo.xlsx"; // 创建一个名为"模板"的 sheet 页,并写入数据 FesodSheet.write(fileName, DemoData.class).sheet("模板").doWrite(data()); }写入调用链同样清晰:FesodSheet.write(path, head)构建 ExcelWriterBuilder,.sheet("模板")指定 sheet 名称,.doWrite(data())完成写入并自动关闭输出流。write方法同样支持File、String路径与OutputStream三种目标,便于对接文件下载响应。
@ExcelProperty:表头与列映射
写入时的表头、列顺序由 ExcelProperty.java 注解控制,它声明在字段上,关键属性如下:
| 属性 | 默认值 | 含义 |
|---|---|---|
value | {""} | 表头名称,可传数组;写入时多个值会自动合并为多级表头,读取时取最后一个作为字段映射 |
index | -1 | 列索引(从 0 开始);为-1时按 Java 类字段声明顺序排列 |
order | Integer.MAX_VALUE | 排序号,优先级低于index |
converter | AutoConverter.class | 强制该字段使用指定类型转换器 |
源码注释给出的优先级规则是:index>order> 默认排序。也就是说,当表头顺序与字段声明顺序不一致,或需要跳过某些列时,可以显式指定index;当只需调整相对顺序时,用order即可。
@ExcelIgnore:排除字段
示例中ignore字段标注了 @ExcelIgnore,含义是"忽略该字段的 Excel 转换"——它既不会出现在写入的表头和内容中,读取时也会被跳过。对于 id、内部标志位等无需落表的字段,这是最直接的排除手段。
sheet 名称与多个 sheet
sheet("模板")用于给工作表命名。如果想按索引定位或写入多个 sheet,门面类还提供了writerSheet(Integer sheetNo, String sheetName)方法,配合ExcelWriter使用可以一次导出多个工作表(仓库测试 SimpleDataTest.java 中有写入 sheet0、sheet1 两个工作表再统一读取的完整用例)。需要注意 sheet 名称会经过sensitiveSheetName处理(见 ExcelWriterSheetBuilder.java),且.doWrite()只能在FesodSheet.write(...).sheet(...)这种链式入口下调用,直接使用new ExcelWriterSheetBuilder()会抛出ExcelGenerateException。
源码与测试佐证:读写闭环是自洽的
仓库中的测试工程对上述读写示例做了完整的往返验证。以 SimpleDataTest.java 为例:
readAndWrite:构造 10 条数据 → 写入文件 → 读回 → 断言读回条数为 10 且首条 name 为"Name0";synchronousRead:通过doReadSync()将文件一次性读为内存中的List<SimpleData>列表;sheetNameRead07/sheetNoRead07:验证sheet("simple")按名称、sheet(1)按索引两种定位 sheet 的读取方式;pageReadListener07:使用PageReadListener按每批 5 条分页消费数据;pageReadListenerMultipleSheets07:验证跨多个 sheet 读取时每行数据恰好被回调一次。
测试数据模型 DemoData.java 与文档示例一致(string、date、doubleData三个字段),并注明"字段顺序与 Excel 列顺序一一对应",这印证了默认按字段声明顺序映射的约定。如果你需要将整个文件直接读入内存列表(数据量较小时),可以参考 简单读取 文档中的doReadSync()用法:
List<DemoData> list = FesodSheet.read(fileName) .head(DemoData.class) .sheet() .doReadSync();进阶方向
本文覆盖的是官方文档中的最小示例。进一步深入时,可以沿以下路径继续:
- 读取细节:列索引解析、无 POJO 的
Map读取、读取指定行数范围,见 简单读取; - 写入细节:多级表头、样式、合并单元格与填充,见 写入 系列文档;
- 类型转换:日期格式、数字格式与自定义转换器,见 转换器;
- CSV 支持:
fesod-sheet同时提供 CSV 读写能力,配合charset参数使用,见 CSV 读取。
小结
通过本文的简单示例可以看出,Fesod Sheet 的读写 API 高度对称:读取用FesodSheet.read(...).sheet().doRead()配合ReadListener,写入用FesodSheet.write(...).sheet(...).doWrite(data)配合@ExcelProperty注解,二者都以"门面方法 + 构建器链"的形式收敛了复杂度。示例中的DemoData既是读取的映射目标,也是写入的数据模型,同一套注解可以同时服务导入与导出,这正是它适合作为业务中"报表导出 / 数据导入"模块起步模板的原因。
- 后端
【免费下载链接】fesod
Fast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.
相关推荐
PhpSpreadsheet 快速上手指南:使用纯 PHP 读写 Excel 电子表格
PhpSpreadsheet 快速上手指南:使用纯 PHP 读写 Excel 电子表格 PhpSpreadsheet 是一套用纯 PHP 编写的类库,提供了一组
后端Apache Fesod(Incubating) Fesod Sheet 快速上手:一个示例玩转 Excel 读写
Apache Fesod Incubating Fesod Sheet 快速上手:一个示例玩转 Excel 读写 Apache Fesod Incubating
后端5分钟快速上手:Jspreadsheet电子表格的完整使用指南
5分钟快速上手:Jspreadsheet电子表格的完整使用指南 想要在网页中创建功能强大的电子表格吗?Jspreadsheet CE v5是一个轻量级的纯Jav
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考