资讯详情

资讯详情

Apache Fesod POJO 写入实战:按参数筛选列、控制列顺序与无模型导出

后端【免费下载链接】fesodFast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.项目地址https://gitcode.com/gh_mirrors/fast/fesod点击查看免费下载Apache FesodIncubating是专注于大数据量电子表格处理的开源框架其核心入口FesodSheet提供了一套流式、低内存占用的读写 API。本篇技术指南围绕 Fesod 的POJO 写入主题展开覆盖三类高频实战场景按参数动态导出指定列、精确控制列的写入顺序、以及不创建实体类的无模型No Model导出。读完本文你将掌握excludeColumnFieldNames/includeColumnFieldNames/orderByIncludeColumn/ExcelProperty(index)等核心参数与注解的用法与底层语义并能在自己的导出接口中直接落地。文中所有示例均可在仓库中找到对应源码佐证核心写入口位于 FesodSheet.java写参数定义于 WriteBasicParameter.java列筛选与重排的底层实现在 ClassUtils.java配套测试见 ExcludeOrIncludeDataTest.java。准备工作FesodSheet.write()与 POJO 约定开始之前先理解写入口的构建链。FesodSheet提供了write(File)、write(String pathName)、write(OutputStream)三个重载以及各自带Class head的版本最终都返回ExcelWriterBuilder由 FesodSheet.java 中file(...).headIfNotNull(...)完成初始化FesodSheet.write(fileName, DemoData.class) // 指定输出文件与模型 Class .sheet() // 进入 sheet 级配置 .doWrite(data()); // 写入数据列表POJO 模型通过ExcelProperty注解声明表头与列位置。以 Simple Writing 章节中的DemoData为例其字段为string、date、doubleDataGetter Setter EqualsAndHashCode 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; // 被忽略的字段 }ExcelProperty注解由 ExcelProperty.java 定义包含四个核心属性属性默认值说明value(){}表头名称可传多个值实现多级表头写入时自动合并读取时取最后一个index()-1列的绝对位置从 0 开始为-1时按 Java 类字段声明顺序排序order()Integer.MAX_VALUE列排序权重converter()AutoConverter.class强制该字段使用指定类型转换器需要特别留意注解注释中的优先级约定index order 默认排序即显式声明了index的列其位置以index为准。根据参数动态导出指定列实际业务中导出全部列 往往不够用接口可能要求按用户勾选动态决定输出哪些列。Fesod 提供两种互补的集合参数且集合中装的是POJO 字段名field name而不是表头标题。排除指定列excludeColumnFieldNames除集合中列出的字段外其余字段全部写出Test public void excludeColumnWrite() { String fileName excludeColumnFieldWrite System.currentTimeMillis() .xlsx; SetString excludeColumns Collections.singleton(date); FesodSheet.write(fileName, DemoData.class) .excludeColumnFieldNames(excludeColumns) .sheet() .doWrite(data()); }结果date列消失string与doubleData两列保留AB1String TitleNumber Title2String00.563String10.564String20.56⋮……11String90.56仅导出指定列includeColumnFieldNames只写出集合中列出的字段Test public void includeColumnWrite() { String fileName includeColumnFieldWrite System.currentTimeMillis() .xlsx; SetString includeColumns Collections.singleton(date); FesodSheet.write(fileName, DemoData.class) .includeColumnFieldNames(includeColumns) .sheet() .doWrite(data()); }结果仅保留date一列A1Date Title22026-07-31 20:50:23⋮…112026-07-31 20:50:23底层原理字段过滤发生在头部构建阶段这两个参数并不是写入时临时裁剪数据而是在模型头部Head构建阶段就完成了字段的取舍。以 ClassUtils.java 的doDeclaredFields为例通过FieldUtils.resolveAllFields(clazz)解析出类的全部字段剔除ExcelIgnore标注的字段判断写参数中是否存在excludeColumnFieldNames/excludeColumnIndexes/includeColumnFieldNames/includeColumnIndexes任一配置若命中writeHolder.ignore(fieldName, index)该字段被加入忽略集并从有序字段图中移除剩余字段重新分配连续的列索引得到最终FieldCache。注意exclude与include两套参数中WriteBasicParameter见 WriteBasicParameter.java同时定义了基于列索引的excludeColumnIndexes/includeColumnIndexes与基于字段名的两个集合版本可按需混用。Builder 上同时存在excludeColumnFiledNames拼写错误与excludeColumnFieldNames两个方法前者已标记Deprecated参见 AbstractExcelWriterParameterBuilder.java新代码请统一使用excludeColumnFieldNames/includeColumnFieldNames。测试 ExcludeOrIncludeDataTest.java 的excludeFieldName用例验证了该行为排除column1、column3、column4后回读结果仅剩column2一列。指定列顺序写入默认情况下POJO 模型各列按字段声明顺序依次排列。当需要精细控制列位置时Fesod 提供了注解与参数两种手段。方式一ExcelProperty(index n)指定绝对列位Getter Setter EqualsAndHashCode public class IndexData { ExcelProperty(value String Title, index 0) private String string; ExcelProperty(value Date Title, index 1) private Date date; ExcelProperty(value Number Title, index 3) private Double doubleData; }写入时无需任何额外参数Test public void indexWrite() { String fileName indexWrite System.currentTimeMillis() .xlsx; FesodSheet.write(fileName, IndexData.class) .sheet() .doWrite(data()); }结果string在第 0 列、date在第 1 列、doubleData在第 3 列ABCD1String TitleDate Title(空)Number Title2String02026-07-31 20:50:23(空)0.56重要语义提醒index是从 0 开始的绝对列位置而不是排序键。上面IndexData声明了0、1、3所以第 2 列C 列刻意留空且这个空位会原样保留在输出文件中。若希望三列紧挨着排应依次编号0、1、2。从源码看index的解析遵循 ExcelProperty.java 中声明的优先级index order 默认排序index为-1时回退到类字段顺序。方式二includeColumnFieldNames的组合顺序当与includeColumnFieldNames配合使用时需要注意一个反直觉的默认行为列的输出顺序是 POJO 字段的声明顺序而不是集合的遍历顺序。即使集合把doubleData写在string前面输出时string依然排第一Test public void includeColumnOrderWrite() { String fileName includeColumnFieldWrite System.currentTimeMillis() .xlsx; SetString includeColumns new LinkedHashSet(Arrays.asList(doubleData, string)); FesodSheet.write(fileName, DemoData.class) .includeColumnFieldNames(includeColumns) .sheet() .doWrite(data()); }结果string在前、doubleData在后与DemoData字段声明顺序一致而非集合顺序AB1String TitleNumber Title2String00.56方式三orderByIncludeColumn(true)按集合顺序输出若希望列顺序与传入集合的顺序完全一致追加.orderByIncludeColumn(true)即可Test public void orderByIncludeColumnWrite() { String fileName includeColumnFieldWrite System.currentTimeMillis() .xlsx; SetString includeColumns new LinkedHashSet(Arrays.asList(doubleData, string)); FesodSheet.write(fileName, DemoData.class) .includeColumnFieldNames(includeColumns) .orderByIncludeColumn(true) .sheet() .doWrite(data()); }结果doubleData反超string列顺序变为集合顺序AB1Number TitleString Title20.56String0关键前提orderByIncludeColumn依赖集合具备稳定的迭代顺序请使用LinkedHashSet或List不要使用HashSet——后者的迭代顺序不确定会导致列顺序随机化。底层原理resortField的重排逻辑orderByIncludeColumn的语义由 ClassUtils.java 的resortField实现其注释明确该方法仅在includeColumnFieldNames/includeColumnIndexes有值且orderByIncludeColumn为true时生效当配置的是字段名集合时遍历集合为每个字段名分配递增的临时索引filedIndexMap随后重建sortedFieldMap集合中第 N 个字段落在第 N 列当配置的是索引集合时同理将原始列索引映射为连续的临时索引若重排后字段的新位置与旧位置不同旧的indexFieldMap条目会被移除即注解指定的顺序在此场景下失效以集合顺序为准。测试 ExcludeOrIncludeDataTest.java 的includeFieldNameOrder用例验证集合按column4、column2、column3传入后回读的列顺序恰为column4 → column2 → column3与声明顺序无关。不创建对象的无模型写入如果数据来自数据库动态查询、列结构在运行期才能确定此时不必强行设计实体类可以用ListListString定义表头、ListListObject定义数据直接写入。代码示例Test public void noModelWrite() { String fileName noModelWrite System.currentTimeMillis() .xlsx; FesodSheet.write(fileName) .head(head()) // 动态表头 .sheet(Write Without Object) .doWrite(dataList()); } private ListListString head() { return Arrays.asList( Collections.singletonList(String Title), Collections.singletonList(Number Title), Collections.singletonList(Date Title)); } private ListListObject dataList() { ListListObject list new ArrayList(); for (int i 0; i 10; i) { list.add(Arrays.asList(String i, 0.56, new Date())); } return list; }结果三列表头 十行数据ABC1String TitleNumber TitleDate Title2String00.562026-07-31 20:50:233String10.562026-07-31 20:50:23⋮………11String90.562026-07-31 20:50:23要点说明head()返回ListListString内层 List 代表一行表头内层只有一个元素即单级表头若内层含多个元素则构成多级合并表头配合automaticMergeHead默认true见 ExcelWriterBuilder.java 与 AbstractExcelWriterParameterBuilder.java自动合并单元格FesodSheet.write(fileName)不传模型 Class 时通过.head(head())手动注入表头数据行的每个元素会走内置的类型转换器字符串原样写出、Double输出为数值单元格、Date按默认日期格式写出因此dataList使用ListListObject容纳异构类型.sheet(Write Without Object)指定了 sheet 名称等价于sheet(null, sheetName)重载。小结需求推荐手段动态剔除若干列excludeColumnFieldNames(CollectionString)集合装字段名动态仅保留若干列includeColumnFieldNames(CollectionString)集合装字段名固定精确的列位置ExcelProperty(value ..., index n)index从 0 起为绝对列位支持留空列让列顺序跟随传入集合includeColumnFieldNames(...).orderByIncludeColumn(true)配合LinkedHashSet/List不建实体类直接导出FesodSheet.write(path).head(ListListString).sheet().doWrite(ListListObject)这三类能力覆盖了从固定模型导出到运行时动态导出的完整谱系字段级过滤让导出接口可以按用户勾选裁剪列index与orderByIncludeColumn让列顺序可控、可解释无模型写入则彻底解耦了实体类设计与动态列场景。若要继续深入可进一步阅读 Simple Writing 了解基础写入全貌或在 write 目录下查看表头、格式、样式等进阶章节对读取端 POJO 映射感兴趣的话可参考 POJO 读取。赞分享后端【免费下载链接】fesodFast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM.项目地址https://gitcode.com/gh_mirrors/fast/fesod点击查看免费下载相关推荐Apache Flink 数据类型与序列化机制完全指南TypeInformation、POJO 判定与 Kryo/Avro 序列化实战Apache Flink 数据类型与序列化机制完全指南TypeInformation、POJO 判定与 Kryo/Avro 序列化实战 Apache Flin后端大数据流处理批处理BenchmarkDotNet 参数列排序使用 [Params] 的 Priority 属性控制结果表列顺序BenchmarkDotNet 参数列排序使用 Params 的 Priority 属性控制结果表列顺序 导读 在 BenchmarkDotNet 中当基准性能测试开发工具antd Table 列顺序控制用 Table.EXPAND_COLUMN 与 Table.SELECTION_COLUMN 精确定位展开列与选择列antd Table 列顺序控制用 Table.EXPAND_COLUMN 与 Table.SELECTION_COLUMN 精确定位展开列与选择列 导读 在前端UI组件设计系统上一篇WebdriverIO与GitLab CI集成完整测试流水线配置与并行执行优化下一篇终极Godot逆向工程工具gdsdecomp完整解析与实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →