ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Fesod 读取 Excel 表头指南:invokeHead 回调、多行表头与 head() 映射详解

Fesod 读取 Excel 表头指南:invokeHead 回调、多行表头与 head() 映射详解 后端【免费下载链接】fesodFast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.项目地址https://gitcode.com/gh_mirrors/fast/fesod点击查看免费下载本文面向使用 Apache FesodIncubating读取 Excel 的开发者系统讲解读取表头数据的三种核心方式通过监听器invokeHead回调捕获表头行、通过headRowNumber参数处理多行表头、以及通过head()方法指定表头 POJO 完成表头与实体字段的映射。读完本文你将掌握表头读取的完整调用链与底层判定逻辑能够应对单行表头、多行合并表头、无表头等各类真实场景。表头读取概述在读取 Excel 时表头Head是指数据行之前用于描述列含义的若干行。Fesod 在 SAX 逐行解析电子表格的过程中会依据配置的表头行数自动区分表头行与数据行并将表头行单独交给监听器的invokeHead方法处理。读取表头数据的基本做法是继承AnalysisEventListener重写invokeHead方法即可在解析到每个表头行时收到回调。这一机制由 ReadListener 接口定义/** * When analysis one head row trigger invoke function. * * param headMap * param context */ default void invokeHead(MapInteger, ReadCellData? headMap, AnalysisContext context) {}headMap的键为列索引从 0 开始值为该单元格的ReadCellData?对象——它保留了单元格的类型、格式化后的值等元信息而不仅是字符串。一、通过 invokeHead 读取表头数据监听器实现实现一个专门接收表头数据的监听器示例代码如下Slf4j public class DemoHeadDataListener extends AnalysisEventListenerDemoData { Override public void invokeHead(MapInteger, ReadCellData? headMap, AnalysisContext context) { log.info(解析到表头数据: {}, JSON.toJSONString(headMap)); } Override public void invoke(DemoData data, AnalysisContext context) { } Override public void doAfterAllAnalysed(AnalysisContext context) { } }其中invoke(DemoData data, AnalysisContext context)与doAfterAllAnalysed(AnalysisContext context)是ReadListener接口的抽象方法即使不处理数据也必须提供实现。invokeHeadMap直接获取字符串形式的表头细心的读者会发现AnalysisEventListener在实现invokeHead时做了一个默认转换它先把MapInteger, ReadCellData?通过ConverterUtils.convertToStringMap转换为MapInteger, String再调用invokeHeadMap。见 AnalysisEventListenerOverride public void invokeHead(MapInteger, ReadCellData? headMap, AnalysisContext context) { invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context); } /** * Returns the header as a map.Override the current method to receive header data. */ public void invokeHeadMap(MapInteger, String headMap, AnalysisContext context) {}因此你有两个选择重写invokeHead拿到带类型信息的ReadCellData?适合需要精确判断单元格类型如数字表头的场景重写invokeHeadMap直接拿到MapInteger, String的纯文本表头适合大多数只关心表头文字的校验、比对场景。触发时机与底层判定逻辑invokeHead并非读完表头后一次性触发而是每解析到一行表头行都会触发一次。行类型的判定发生在 DefaultAnalysisEventProcessor.dealData 中int rowIndex readRowHolder.getRowIndex(); int currentHeadRowNumber analysisContext.readSheetHolder().getHeadRowNumber(); boolean isData rowIndex currentHeadRowNumber; ... if (isData) { // handle data row readListener.invoke(readRowHolder.getCurrentRowAnalysisResult(), analysisContext); } else { // handle data header readListener.invokeHead(cellDataMap, analysisContext); }可见当行索引rowIndex小于表头行数headRowNumber时该行被当作表头行回调invokeHead否则回调invoke。默认headRowNumber为 1即第一行是表头从第二行开始是数据。完整读取代码配合监听器即可完成一次读取Test public void headerRead() { String fileName path/to/demo.xlsx; FesodSheet.read(fileName, DemoData.class, new DemoHeadDataListener()) .sheet() .doRead(); }FesodSheet.read的第二个参数DemoData.class指定了数据模型第三个参数传入监听器.sheet()选择工作表默认第一个.doRead()开始流式解析。二、多行表头读取现实中的 Excel 经常使用两行甚至多行合并表头例如区域 分组 具体指标的三级结构。Fesod 提供两种方式解析多行表头显式设置headRowNumber参数依靠实体类上的ExcelProperty注解自动推导表头结构。headRowNumber 参数headRowNumber的语义在 ReadBasicParameter 中有明确注释0该 Sheet 没有表头第一行就是数据1该 Sheet 有一行表头这是默认值2该 Sheet 有两行表头从第三行开始才是数据。通过 AbstractExcelReaderParameterBuilder.headRowNumber 即可在读取链路上配置Test public void complexHeaderRead() { String fileName path/to/demo.xlsx; FesodSheet.read(fileName, DemoData.class, new DemoDataListener()) .sheet() // 设置多行表头的行数默认为 1 .headRowNumber(2) .doRead(); }设置为 2 后前两行都会被当作表头行回调invokeHead触发两次从第三行起的数据行才回调invoke。若表头为 0 行则第一行数据即被当作数据行处理。依据实体类注解自动解析多行表头当数据模型通过ExcelProperty注解声明了多层表头时Fesod 会在读取结束时根据最后一行表头自动完成列匹配详见下文表头映射原理。仓库测试 ComplexHeadData 展示了典型的三级表头写法Getter Setter EqualsAndHashCode public class ComplexHeadData { ExcelProperty({Region, Region, Merged}) private String string0; ExcelProperty({Region, Region, Merged}) private String string1; ExcelProperty({Region, Group, Group}) private String string2; ExcelProperty({Region, Group, Group}) private String string3; ExcelProperty({Region}) private String string4; }ExcelProperty的value是String[]类型见 ExcelProperty默认{}数组长度即表头行数数组顺序即从上到下的表头层级。例如{Region, Group, Group}表示第一行表头为 Region、第二行表头为 Group、第三行表头为 Group。对应的读写往返测试见 ComplexHeadDataTest。提示ComplexHeadDataTest中同时出现了automaticMergeHead(Boolean.FALSE)的写侧用法说明读侧的多级表头结构可以由写侧通过相同注解生成二者相互对应便于构造回归测试。三、通过 head() 指定表头 POJO在某些场景下读取时并未在FesodSheet.read(...)中直接传入实体类例如不确定表结构、需要运行时决定模型此时可以使用head()方法单独指定表头 POJO将表头解析与数据行解析解耦Test public void headerPojoRead() { String fileName path/to/demo.xlsx; FesodSheet.read(fileName, new DemoDataListener()) .head(DemoData.class) .sheet() .doRead(); }head()有三种重载形式均定义在 AbstractParameterBuilder 中head(Class? clazz)以实体类的ExcelProperty注解定义表头即上文示例的用法head(ListListString head)直接以字符串列表指定表头适合表头完全动态、无法预先建模的场景head(ConsumerHeadBuilder headBuilderConsumer)通过HeadBuilder编程式构建表头可精细控制每个字段的名称、索引等。其中head(Class?)会被包装为HeadKindEnum.CLASS类型的表头属性ExcelReadHeadProperty读取时用于驱动列匹配与实体字段填充。四、表头映射原理buildHead 的列匹配过程当使用基于类的表头HeadKindEnum.CLASS时Fesod 在解析完最后一行表头后执行 buildHead完成表头文本 → 实体字段列索引的映射。整个过程可分为三步判定表头结束行dealData中当!isData currentHeadRowNumber rowIndex 1时说明当前行是最后一行表头随即调用buildHead记录最大非空表头列过滤掉CellDataTypeEnum.EMPTY的空单元格后取最大列号写入setMaxNotEmptyDataHeadSize供后续读取列数校验使用按名称匹配列索引遍历实体属性对应的Head对象取注解value数组的最后一个元素即最底层表头文本与最后一行表头逐列比对命中后通过headData.setColumnIndex(stringKey)将该列的索引绑定到该属性上。匹配时还体现了两个值得注意的细节强制索引优先源码中if (headData.getForceIndex() || !headData.getForceName())的分支会跳过名称匹配直接从源码结构看这说明注解体系同时支持按索引定位与按名称匹配两种模式且按索引模式拥有更高优先级文本规整匹配前会根据全局配置AutoStrip/AutoTrim对表头文本做去空白处理StringUtils.strip或String.trim以容忍表头单元格两侧多余的空格。五、常见问题与建议无表头文件若第一行就是数据设置.headRowNumber(0)即可跳过表头逻辑第一行将直接回调invoke只想校验表头不想建模优先重写invokeHeadMap(MapInteger, String, ...)把表头转成字符串 Map 后与预期文案比对简单直观多级表头与数据行错位务必确认headRowNumber与实际表头行数一致否则数据行的起始索引会整体偏移导致首行数据被误判为表头或反之表头带空格/换行Fesod 在buildHead阶段已对表头文本进行 strip/trim 处理实体注解中应写干净文本即可。小结Fesod 的表头读取能力由监听器回调invokeHead/invokeHeadMap、读取参数headRowNumber与表头构建器head()三部分组成监听器回调负责在正确时机交付表头内容headRowNumber决定表头与数据的行分界head()则在运行时灵活指定表头来源。理解 DefaultAnalysisEventProcessor 中的行判定与列匹配逻辑后你便可以在实际项目中自如处理从单行表头到多级合并表头的各种表格结构。赞分享后端【免费下载链接】fesodFast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.项目地址https://gitcode.com/gh_mirrors/fast/fesod点击查看免费下载相关推荐Apache Fesod 表头读取指南invokeHead 监听、多行表头与表头 POJO 的完整实战Apache Fesod 表头读取指南invokeHead 监听、多行表头与表头 POJO 的完整实战 导读 本文聚焦 Apache FesodIncuba后端EasyExcel表头映射终极指南3个技巧解决Excel数据读取难题EasyExcel表头映射终极指南3个技巧解决Excel数据读取难题 还在为Excel表头变化而头疼吗想要快速掌握EasyExcel的智能映射技巧本指南将后端Apache Fesod 表头写入完全指南多级表头、动态表头与合并策略HeaderMergeStrategyApache Fesod 表头写入完全指南多级表头、动态表头与合并策略HeaderMergeStrategy 导读 本文是 Apache FesodIn后端上一篇【特别福利】Cloudpods项目部署中宿主机节点信息获取问题分析下一篇【特别分享】AntDesign Blazor 表格组件状态恢复异常问题解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表