☰
Java 企业级工具类全家桶-58-Excel表格读取工具类
2026/10/9 5:36:03 网站建设 项目流程

📌拿来即用: Java 企业级工具类全家桶-58-Excel表格读取工具类

📋 目录

  • 一、工具类功能
  • 二、所需环境
  • 三、方法概览(按需调用)
  • 四、调用示例(直观体验)
  • 五、工具类源码(可直接复制)

一、工具类功能

基于阿里 EasyExcel 的表格读取工具类,接住「按 sheet 名读单表、读全部 sheet、大文件逐行流式消费」三类需求,行数据映射成标注 @ExcelProperty 的实体。拿回来的是填好的实体列表、按 sheet 名分组的有序 Map,或实际交付的行数。

表头行数与是否丢弃整行空白都可指定,结果一律不为 null,sheet 名首尾空白先裁再匹配。面向中小体量表格的整体读取与单表流式导入,不做公式计算、样式解析与超大文件分片。


二、所需环境

JDK 17或以上 + Spring Boot 3.x或以上

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency>

三、方法概览(按需调用)

序号方法入参返回用途
1readBySheetName(String, String, int, Class)表格文件路径 + 工作表名 + 表头行数 + 映射实体类型List按名称读单个 sheet,保留空行
2readBySheetName(File, String, int, Class, boolean)表格文件 + 工作表名 + 表头行数 + 映射实体类型 + 是否丢弃空行List读单个 sheet,可选丢弃整行空白
3readAllSheets(String, int, Class)表格文件路径 + 表头行数 + 映射实体类型Map<String,List>一次读全部 sheet,保留空行
4readAllSheets(File, int, Class, boolean)表格文件 + 表头行数 + 映射实体类型 + 是否丢弃空行Map<String,List>读全部 sheet,可选丢弃整行空白
5readAllSheets(Path, int, Class)表格文件路径 + 表头行数 + 映射实体类型Map<String,List>Path 入口读全部 sheet,保留空行
6readBySheetName(File, String, int, Class, boolean, Consumer<? super T>)表格文件 + 工作表名 + 表头行数 + 映射实体类型 + 是否丢弃空行 + 行消费者int逐行流式消费单个 sheet,返回交付行数

四、调用示例(直观体验)

调用示例直接复制进 IDE 右键 Run 就能看到调用工具类各方法的输出结果。

21:00:30.201[main]INFO--「EasyExcelReadUtils方法1readBySheetName(String,String,int,Class<T>)」返回数据列表->[OrderRow{orderNo=ORD-1,amount=100.50,remark=正常},OrderRow{orderNo=null,amount=null,remark=null},OrderRow{orderNo=ORD-2,amount=200.00,remark=null}]21:00:30.223[main]INFO--「EasyExcelReadUtils方法2readBySheetName(File,String,int,Class<T>,boolean)」丢弃映射列全空的行->[OrderRow{orderNo=ORD-1,amount=100.50,remark=正常},OrderRow{orderNo=ORD-2,amount=200.00,remark=null}]21:00:30.239[main]INFO--「EasyExcelReadUtils方法3readAllSheets(String,int,Class<T>)」返回按 sheet 分组->{6月订单=[OrderRow{orderNo=ORD-1,amount=100.50,remark=正常},OrderRow{orderNo=null,amount=null,remark=null},OrderRow{orderNo=ORD-2,amount=200.00,remark=null}],退货=[OrderRow{orderNo=RET-9,amount=-50.00,remark=退款}]}21:00:30.253[main]INFO--「EasyExcelReadUtils方法4readAllSheets(File,int,Class<T>,boolean)」丢弃空行后的分组->{6月订单=[OrderRow{orderNo=ORD-1,amount=100.50,remark=正常},OrderRow{orderNo=ORD-2,amount=200.00,remark=null}],退货=[OrderRow{orderNo=RET-9,amount=-50.00,remark=退款}]}21:00:30.266[main]INFO--「EasyExcelReadUtils方法5readAllSheets(Path,int,Class<T>)」返回按 sheet 分组->{6月订单=[OrderRow{orderNo=ORD-1,amount=100.50,remark=正常},OrderRow{orderNo=null,amount=null,remark=null},OrderRow{orderNo=ORD-2,amount=200.00,remark=null}],退货=[OrderRow{orderNo=RET-9,amount=-50.00,remark=退款}]}21:00:30.281[main]INFO--「EasyExcelReadUtils方法6readBySheetName(File,String,int,Class<T>,boolean,Consumer<?superT>)」返回交付行数->2,逐行取到订单号->[ORD-1,ORD-2]21:00:30.293[main]ERROR--「异常信息获取演示」找不到 sheet->未找到名为[不存在]的 sheet,当前文件包含:[6月订单,退货]21:00:30.293[main]ERROR--「异常信息获取演示」文件不存在->Excel文件不存在:没有这个.xlsx21:00:30.293[main]ERROR--「异常信息获取演示」表头行数非法->headRowNumber 必须大于等于1进程已结束,退出代码为0
packagecom.example.order.api;importcom.alibaba.excel.EasyExcel;importcom.alibaba.excel.ExcelWriter;importcom.alibaba.excel.annotation.ExcelProperty;importcom.alibaba.excel.write.metadata.WriteSheet;importcom.example.common.utils.EasyExcelReadUtils;importlombok.extern.slf4j.Slf4j;importjava.io.File;importjava.io.IOException;importjava.math.BigDecimal;importjava.nio.file.Files;importjava.nio.file.Path;importjava.util.ArrayList;importjava.util.Comparator;importjava.util.List;importjava.util.Map;/** * 调用示例:整个文件复制进 IDE,右键 Run 就能看效果。 * * <p>EasyExcel 读写不依赖外部服务,也不需要 Spring 容器;示例在系统临时目录里现造一个含两张 * sheet 的 xlsx,跑完自删,不依赖任何外部样表。表头写四列、实体只映射前三列,中间那行「映射列全空」 * 的数据才会被解析器交付下来,从而看出 skipBlankRows 开与关的差别。 * 日志用 Lombok 的 {@code @Slf4j} + SLF4J 占位符,没装 Lombok 就把 {@code log} 换成项目自己的 Logger。 */@Slf4jpublicclassEasyExcelReadUtilsDemo{/** 示例用的行实体,实际换成你自己的;字段用 @ExcelProperty 标注表头 */publicstaticclassOrderRow{@ExcelProperty("订单号")privateStringorderNo;@ExcelProperty("金额")privateBigDecimalamount;@ExcelProperty("备注")privateStringremark;publicOrderRow(){}publicStringgetOrderNo(){returnorderNo;}publicvoidsetOrderNo(StringorderNo){this.orderNo=orderNo;}publicBigDecimalgetAmount(){returnamount;}publicvoidsetAmount(BigDecimalamount){this.amount=amount;}publicStringgetRemark(){returnremark;}publicvoidsetRemark(Stringremark){this.remark=remark;}@OverridepublicStringtoString(){return"OrderRow{orderNo="+orderNo+", amount="+amount+", remark="+remark+"}";}}/** 样表表头:四列,实体只映射前三列,第四列是业务侧不关心的流水号 */privatestaticfinalList<String>HEAD=List.of("订单号","金额","备注","流水号");publicstaticvoidmain(String[]args)throwsIOException{Pathdir=Files.createTempDirectory("easyexcel-demo");Filesample=dir.resolve("订单.xlsx").toFile();try{writeSample(sample);// ========== 一、按名称读取单个 sheet ==========List<OrderRow>byName=EasyExcelReadUtils.readBySheetName(sample.getPath(),"6月订单",1,OrderRow.class);log.info("「EasyExcelReadUtils 方法1 readBySheetName(String, String, int, Class<T>)」返回数据列表 -> {}",byName);List<OrderRow>skipBlank=EasyExcelReadUtils.readBySheetName(sample,"6月订单",1,OrderRow.class,true);log.info("「EasyExcelReadUtils 方法2 readBySheetName(File, String, int, Class<T>, boolean)」丢弃映射列全空的行 -> {}",skipBlank);// ========== 二、一次读取全部 sheet ==========Map<String,List<OrderRow>>allByName=EasyExcelReadUtils.readAllSheets(sample.getPath(),1,OrderRow.class);log.info("「EasyExcelReadUtils 方法3 readAllSheets(String, int, Class<T>)」返回按 sheet 分组 -> {}",allByName);Map<String,List<OrderRow>>allSkipBlank=EasyExcelReadUtils.readAllSheets(sample,1,OrderRow.class,true);log.info("「EasyExcelReadUtils 方法4 readAllSheets(File, int, Class<T>, boolean)」丢弃空行后的分组 -> {}",allSkipBlank);Map<String,List<OrderRow>>allByPath=EasyExcelReadUtils.readAllSheets(sample.toPath(),1,OrderRow.class);log.info("「EasyExcelReadUtils 方法5 readAllSheets(Path, int, Class<T>)」返回按 sheet 分组 -> {}",allByPath);// ========== 三、逐行流式消费 ==========List<String>orderNos=newArrayList<>();intdelivered=EasyExcelReadUtils.readBySheetName(sample,"6月订单",1,OrderRow.class,true,row->orderNos.add(row.getOrderNo()));log.info("「EasyExcelReadUtils 方法6 readBySheetName(File, String, int, Class<T>, boolean, Consumer<? super T>)」返回交付行数 -> {}, 逐行取到订单号 -> {}",delivered,orderNos);// ========== 四、catch异常信息 ==========// 1. sheet 名找不到:报错会列出文件内全部 sheet 名try{EasyExcelReadUtils.readBySheetName(sample,"不存在",1,OrderRow.class,false);}catch(IllegalArgumentExceptione){log.error("「异常信息获取演示」找不到 sheet -> {}",e.getMessage());}// 2. 文件不存在try{EasyExcelReadUtils.readBySheetName(newFile("没有这个.xlsx"),"6月订单",1,OrderRow.class,false);}catch(IllegalArgumentExceptione){log.error("「异常信息获取演示」文件不存在 -> {}",e.getMessage());}// 3. 表头行数小于 1try{EasyExcelReadUtils.readBySheetName(sample,"6月订单",0,OrderRow.class,false);}catch(IllegalArgumentExceptione){log.error("「异常信息获取演示」表头行数非法 -> {}",e.getMessage());}}finally{deleteQuietly(dir);}}/** 在临时目录里现造 xlsx:两张 sheet,「6月订单」中间夹一行映射列全空的数据,用来演示 skipBlankRows */privatestaticvoidwriteSample(Filesample){WriteSheetjune=EasyExcel.writerSheet(0,"6月订单").build();WriteSheetrefund=EasyExcel.writerSheet(1,"退货").build();try(ExcelWriterwriter=EasyExcel.write(sample).build()){writer.write(List.of(HEAD,List.of("ORD-1","100.50","正常","A01"),List.of("","","","A02"),List.of("ORD-2","200.00","","A03")),june);writer.write(List.of(HEAD,List.of("RET-9","-50.00","退款","B01")),refund);}}/** 递归删除临时目录与其中的样表,先删文件后删目录 */privatestaticvoiddeleteQuietly(Pathdir){try(varpaths=Files.walk(dir)){paths.sorted(Comparator.reverseOrder()).forEach(path->{try{Files.deleteIfExists(path);}catch(IOExceptionignored){// 临时文件删不掉也不影响示例结论}});}catch(IOExceptionignored){// 目录已不存在或被占用,忽略}}}

五、工具类源码(可直接复制)

📦拿来即用: 58-Excel表格读取工具类(java企业级代码).zip

💡 工具类已调试通过,复制粘贴即可使用,省时省力

💡 可保存到自己网盘,永久有效


觉得对您有帮助,麻烦点点关注啦,您的关注是我创作的最大动力~ 🎯

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询