news 2026/10/4 1:51:25

Apache Fesod(Incubating) Fesod Sheet 快速上手:一个示例玩转 Excel 读写

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Apache Fesod(Incubating) Fesod Sheet 快速上手:一个示例玩转 Excel 读写
  • 后端

【免费下载链接】fesod

Fast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.

项目地址:https://gitcode.com/gh_mirrors/fast/fesod
点击查看免费下载

Apache Fesod(Incubating) 的fesod-sheet模块提供了一套以POJO + 注解为核心的电子表格读写 API。本文基于 quickstart/example.md 的官方示例,完整讲解用FesodSheet一个类完成 Excel 读取与写入的最小可运行代码,并结合仓库源码(构建器、监听器、注解实现)深入剖析每条 API 背后的调用链与扩展点。读完本文,你将能在自己的 Maven/Gradle 项目中直接落地「监听式逐行读表」与「注解式模型写表」两套标准用法。

前置准备:引入 fesod-sheet 依赖

fesod-sheet是独立于其他模块发布的核心组件,通过 Maven 引入(版本以 guide.md 中说明的当前版本2.0.2-incubating为准,该版本支持 JDK8 至 JDK25):

<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' }

底层依赖 Apache POI 5.5.1(Excel 处理)、Apache Commons CSV 1.14.1(CSV 支持)与 Ehcache 3.9.11(缓存)。如果你的工程已引入过 POI 相关组件,需要手动排除 POI 相关 jar 以避免版本冲突(详见 guide.md)。

读取电子表格:监听器模式逐行解析

官方示例用「模型类 + 监听器」组合完成读取,核心代码只有一行:

// Implement the ReadListener interface to set up operations for reading data public class DemoDataListener implements ReadListener<DemoData> { @Override public void invoke(DemoData data, AnalysisContext context) { System.out.println("Parsed a data entry" + JSON.toJSONString(data)); } @Override public void doAfterAllAnalysed(AnalysisContext context) { System.out.println("All data parsed!"); } } public static void main(String[] args) { String fileName = "demo.xlsx"; // Read file FesodSheet.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead(); }

读表入口:FesodSheet.read 的多种重载

FesodSheet是 Apache Fesod 电子表格处理的核心门面类(源码见 FesodSheet.java),其read方法根据数据来源提供多组重载:

重载适用场景
read(String pathName)按文件路径读取
read(File file)按文件对象读取
read(InputStream inputStream)按输入流读取(网络流、上传流等)
read(pathName/file/inputStream, Class head)指定表头模型类
read(pathName/file/inputStream, Class head, ReadListener listener)指定模型类与读取监听器(示例所用)

所有重载最终都会构造一个 ExcelReaderBuilder,调用链为read(...)→new ExcelReaderBuilder().file(xxx).headIfNotNull(head).registerReadListenerIfNotNull(listener),即官方示例中的FesodSheet.read(fileName, DemoData.class, new DemoDataListener())等价于:

FesodSheet.read() .file(fileName) // 数据来源 .head(DemoData.class) // 模型类(表头/字段映射依据) .registerReadListener(new DemoDataListener()) // 注册监听器 .sheet() // 选择工作表 .doRead(); // 触发读取

监听器核心方法:ReadListener 接口全解

示例中的DemoDataListener实现了 ReadListener 接口。该接口定义了读取过程中的全部生命周期回调,其中invoke与doAfterAllAnalysed是必须实现的两个方法:

  • void invoke(T data, AnalysisContext context):每解析出一行数据就回调一次。data就是当前行的模型对象(与context.readRowHolder()中持有的行数据一致);context是分析上下文,可从中拿到行号、工作表、工作簿等运行期信息。
  • void doAfterAllAnalysed(AnalysisContext context):所有数据解析完成后回调,常用于收尾(如关闭资源、统计总数、释放分页处理状态)。
  • default void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context):表头行解析完成时回调,可用于校验表头或做动态列名映射。
  • default void onException(Exception exception, AnalysisContext context):任一监听器上报异常时触发;如果在此抛出异常,整个读取过程将终止。
  • default void extra(CellExtra extra, AnalysisContext context):开启额外信息读取(超链接、批注、合并单元格)时回调。
  • default boolean hasNext(AnalysisContext context):控制是否继续读取下一条数据,返回false可提前终止(其默认实现会依据numRows行数上限判断,见 ReadListener.java)。

示例中打印数据使用了JSON.toJSONString(data)(fastjson),这是演示性写法,实际工程中你也可以直接System.out.println(data)或调用 POJO 自身的toString()。

触发读取:sheet().doRead() 的底层链路

.sheet()返回 ExcelReaderSheetBuilder,doRead()内部完成两件事:

public void doRead() { excelReader.read(build()); // 将 ReadSheet 参数交给 ExcelReader 执行 excelReader.finish(); // 收尾并关闭资源 }

ExcelReader.read()会根据文件类型(xlsx/xls/csv)选择对应的 SAX 解析器(如XlsxSaxAnalyser、XlsSaxAnalyser)逐行解析,解析出的每一行经转换器(Converter)转换为模型对象后回调invoke——这正是「流式读取、不把整个文件装入内存」的设计基础,也是 Fesod 处理大文件不易 OOM 的关键。相关实现见 analysis/v07/XlsxSaxAnalyser.java 与 analysis/v03/XlsSaxAnalyser.java。

读取常用可选项

通过构建器链,你还可以在sheet()之前或之上附加读取参数:

FesodSheet.read(fileName, DemoData.class, listener) .ignoreEmptyRow(false) // 是否忽略空行,默认 true .numRows(100) // 最多读取 100 行(含表头) .sheet("Sheet1") // 按名称选择工作表 .doRead();

sheet()支持无参(默认第一个工作表)、sheet(Integer sheetNo)(从 0 开始的下标)与sheet(String sheetName)(按名称)。其余参数如password(加密文件)、charset(仅 CSV 生效)、readCache(缓存策略,控制内存占用)、extraRead(读取批注/超链接等额外信息)、readDefaultReturn(无模型类时的默认返回类型)等,均可从 ExcelReaderBuilder 查看完整定义。

写入电子表格:注解模型 + 一行写表

官方示例用「注解模型类」描述表头与列,再用一行doWrite落盘:

// Sample data class public class DemoData { @ExcelProperty("String Title") private String string; @ExcelProperty("Date Title") private Date date; @ExcelProperty("Number Title") private Double doubleData; @ExcelIgnore private String ignore; } // Prepare data to write private static List<DemoData> data() { List<DemoData> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { DemoData data = new DemoData(); data.setString("String" + i); data.setDate(new Date()); data.setDoubleData(0.56); list.add(data); } return list; } public static void main(String[] args) { String fileName = "demo.xlsx"; // Create a "Template" sheet and write data FesodSheet.write(fileName, DemoData.class).sheet("Template").doWrite(data()); }

模型类注解:@ExcelProperty 与 @ExcelIgnore

写入的核心是模型类上的注解(源码见 ExcelProperty.java):

  • @ExcelProperty(String[] value()):定义表头名称。写入时若配置多个值会自动合并为多级表头;读取时取最后一个作为列名。示例中@ExcelProperty("String Title")即声明该字段对应名为 "String Title" 的列。
  • @ExcelProperty(index = 2):指定列索引(从 0 开始)。index = -1时按 Java 字段声明顺序排列;字段排序优先级为index > order > 默认声明顺序。
  • @ExcelProperty(order = N):显式指定列排序权重。
  • @ExcelProperty(converter = XxxConverter.class):为该字段强制指定类型转换器,默认走AutoConverter自动匹配。
  • @ExcelIgnore:标记字段完全忽略,不参与读写(源码见 ExcelIgnore.java)。示例中的ignore字段因此不会出现在生成的表格中。

仓库测试模块中可找到对应的模型样本,例如 readwrite/DemoData.java 使用 Lombok 的@Getter/@Setter/@EqualsAndHashCode简化样板代码,并注明「字段顺序与 Excel 列顺序一一对应」——这正是默认排序(index = -1)时的工作机制。

写表入口:FesodSheet.write 的多种重载

与read对称,FesodSheet.write也提供多组重载(源码见 FesodSheet.java):

重载适用场景
write(String pathName)写入文件路径
write(File file)写入文件对象
write(OutputStream outputStream)写入输出流(如 HTTP 响应下载)
write(pathName/file/outputStream, Class head)指定表头模型类(示例所用)

write(...)同样采用构建器模式:new ExcelWriterBuilder().file(xxx).headIfNotNull(head)。写入过程由 ExcelWriterBuilder 配置:

  • inMemory(Boolean):是否全内存写表,默认false——即默认先写缓存文件再输出,避免大文件 OOM;注释(Comment)与富文本(RichTextString)仅在内存模式下支持。
  • password(String):写加密文件。注意加密需要将整个文件读入内存,非常耗内存。
  • withTemplate(...):基于模板文件写出,模板同样会被读入内存,超大模板可能 OOM。
  • writeExcelOnException(Boolean):即使写出过程中抛异常也保留已生成的文件,默认false。
  • charset(Charset)/withBom(Boolean):仅 CSV 生效,控制编码与 BOM 前缀(避免 Office 打开乱码,默认true)。

指定工作表与触发写出:sheet("Template").doWrite(data())

示例中.sheet("Template")创建名为Template的工作表(sheet(String sheetName)),等价于sheet(Integer sheetNo)按下标或sheet()使用默认表。之后调用doWrite(data())一次性写入整个List<DemoData>。其底层调用链(见 ExcelWriterSheetBuilder.java)为:

excelWriter.write(data, build()); // 执行写入 excelWriter.finish(); // 完成并刷新输出

写入时模型类按注解生成表头行,随后逐行通过写转换器(WriteConverter)把字段值转换为单元格内容。ExcelWriterSheetBuilder还提供两个进阶入口:

  • doWrite(Supplier<Collection<?>> supplier):延迟取数,适合数据量较大、需要按需生成数据的场景。
  • doFill(Object data)/doFill(Object data, FillConfig fillConfig):基于模板做数据填充(fill),对应 write/metadata/fill 下的填充实现。
  • table()/table(Integer tableNo):在同一 sheet 上追加写多张数据表(见 ExcelWriterTableBuilder)。

另外,写入时 sheet 名称会经过长度校验:若超过 MS Excel 允许的最大长度(Workbook.MAX_SENSITIVE_SHEET_NAME_LEN),sensitiveSheetName会将其截断并输出告警日志,防止生成非法文件名(见 ExcelWriterSheetBuilder.java)。

进阶:一行同步读取全部数据

监听器模式适合逐行流式处理;如果你希望像普通方法调用一样直接拿到List<T>,Fesod 提供了同步读取入口(见 ExcelReaderSheetBuilder.java):

List<DemoData> list = FesodSheet.read("demo.xlsx", DemoData.class) .sheet() .doReadSync();

doReadSync()内部注册一个内置的SyncReadListener,读取完成后一次性返回结果列表。由于是全量收集到内存,doReadSync()更适合中小文件;大数据量场景仍建议使用监听器模式配合hasNext()/分页读取控制内存。

结合测试:官方读写场景的佐证

仓库测试模块中大量测试直接采用与示例相同模式的 API 调用,可作为学习参照:

  • readwrite/DemoDataTest.java:基础模型读写往返测试;
  • core/SimpleDataTest.java:最简单模型的无注解读写测试;
  • head/ComplexHeadDataTest.java:多级表头(@ExcelProperty多值合并)场景;
  • sheet/WriteSheetTest.java:多工作表写入场景。

这些测试展示了从「无注解简单模型」到「复杂表头、多 sheet、填充、样式」的渐进用法,是官方示例之外的最佳扩展阅读材料(完整清单见 website/docs/sheet 目录下的 read/write 专题文档)。

小结

围绕官方 quickstart 示例,本文完整落地了 Fesod Sheet 的两条核心操作链路:

  1. 读取:FesodSheet.read(来源, 模型类, 监听器).sheet().doRead(),通过ReadListener的invoke/doAfterAllAnalysed等回调以流式方式逐行消费数据;
  2. 写入:FesodSheet.write(目标, 模型类).sheet("工作表名").doWrite(数据列表),通过@ExcelProperty/@ExcelIgnore注解声明表头与列映射,构建器内部自动完成生成与落盘。

两者都遵循「门面类 → 构建器 → 执行器」的分层设计,既保证了一行代码的上手体验,又通过构建器暴露了大量可调参数(行数限制、缓存、加密、模板、内存模式等),是进入 Fesod Sheet 更高级特性(样式、合并、填充、自定义转换器)的良好起点。

  • 后端

【免费下载链接】fesod

Fast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.

项目地址:https://gitcode.com/gh_mirrors/fast/fesod
点击查看免费下载
上一篇:10up Engineering Best Practices:移动优先响应式设计实现方案终极指南
下一篇:免费重复文件清理指南:Krokiet 如何用 4 种识别模式找出你磁盘里的冗余

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 1:51:22

MCP协议实现AI自主读取功耗数据的技术实践

1. 项目概述&#xff1a;为什么需要让 AI “自己看” 功耗计&#xff1f; “让 AI 自己看功耗计”——这句话乍听像科幻设定&#xff0c;但落到 IoT 工程现场&#xff0c;它其实是一句极其务实的工程宣言。我第一次在产线调试边缘网关时&#xff0c;就卡在了这个环节&#xff…

作者头像 李华
网站建设 2026/10/4 1:51:20

STM32F103开发板入门指南:从开箱到进阶的完整学习路线

开发板到手的那一刻&#xff0c;确实挺兴奋的。STM32-103的开发板&#xff0c;也就是基于STM32F103芯片的那些板子&#xff0c;可能是国内学习嵌入式接触最多的一类硬件了。不管你是电子相关专业的学生&#xff0c;还是工作后转行想搞单片机&#xff0c;这个板子基本是绕不过去…

作者头像 李华
网站建设 2026/10/4 1:50:07

CubeFS libsdk 用户态 SDK 使用手册:C 接口、构建与文件操作全指南

存储分布式文件系统对象存储云原生 【免费下载链接】cubefs cloud-native distributed storage 项目地址&#xff1a; https://gitcode.com/gh_mirrors/cu/cubefs 点击查看 免费下载 本指南基于 CubeFS 官方开发文档&#xff0c;系统讲解 libsdk&#xff08;用户态客户端库&am…

作者头像 李华
网站建设 2026/10/4 1:49:03

56页数据中心建设方案PPT:从框架到汇报的完整指南

简介&#xff1a;这份56页PPT系统梳理数据中心建设与方案设计全流程&#xff0c;涵盖选址规划、土建装修、电气与空调新风、弱电安防、消防及总控中心等各子系统&#xff0c;面向数据中心规划、运维及售前工程师&#xff0c;帮助读者建立从总体原则到工程落地的完整认知。资源为…

作者头像 李华
网站建设 2026/10/4 1:49:03

CloudBeaver 开发指南:从项目地图到模块化规范的完整解读

后端数据库客户端前端 【免费下载链接】cloudbeaver Cloud Database Manager 项目地址&#xff1a; https://gitcode.com/gh_mirrors/cl/cloudbeaver 点击查看 免费下载 CloudBeaver 是一个开源、基于 Web 的数据库管理应用&#xff08;Cloud Database Manager&#xff09;&am…

作者头像 李华