一、前言今天带大家集成easyExcel。我之所以用这个是因为easyExcel性能比较好,不会报OOM!市面上常见的导入导出Excel有三种:hutooleasyExcelpoihutool和easyExcel都是poi的封装,使用起来比较方便!2.导入依赖这里编辑器是3.0.X版本。不同的版本可能会导致一些差异。如果你的版本是3.1.X,可以去官方文档看看有没有区别!官方文档:https://easyexcel.opensource.alibaba.com/com.alibabaeasyexcel3.0.53.这里实体类可以自带的转换器:@DateTimeFormat("Yyyy年MM月dd日HH时mm分ss秒")LocalDateTimeStringConverter或者自定义转换器:implementation:implementsConverter。具体文档:官方文档:https://easyexcel.opensource.alibaba.com/docs/3.0.x/quickstart/read#%E6%97%A5%E6%9C%9F%E6%95%B0%E5%AD%97%E6%88%96%E8%80%85%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%BC%E5%BC%8F%E8%BD%AC%E6%8D%A2@ExcelProperty参数注意:不建议同时使用index和name,要么一个对象只用index,要么一个对象只用name匹配。使用名称来匹配。这里需要注意的是,如果名称重复,则只有一个字段会读取数据。/***@authorwangzhenjun*@date2022/12/215:52*/@DatapublicclassTest{@TableIdprivateIntegerid;@ExcelProperty(index=0)私有字符串名称;@ExcelProperty(index=1)私有整数年龄;@ExcelProperty(index=2,converter=LocalDateTimeStringConverter.class)privateLocalDateTimetime;}4.写监听器注意事项:这个监听器不能是单例,spring默认管理为单例。如果要使用@Component,一定要加上:@Scope("prototype"),这样创建之后spring就不会管了,每次都是new一个bean!导入时不要加@Component执行newImportDataListener!这里小编不要新人,就这么写吧!!如果你不想这样,你可以使用构造函数集来使用它!BATCH_COUNT:数据阈值,超过会清空list,之前可以保存到数据库中,方便内存回收,防止OOM!这里保存到数据库一般使用批量保存,不要解析成一行再保存到数据库中,这样数据量大会增加对数据库的IO,导致挂掉!这里小编使用ServiceImpl的saveBatch()方法,也可以自己写。如果像小编这样写,会出现循环依赖,加@Lazy即可!/***@authorwangzhenjun*@date2022/12/215:38*/@Slf4j@Component//Bean每次都是新的,不要单例@Scope("prototype")publicclassImportDataListenerimplementsReadListener{@Autowired@LazyprivateTestServicetestService;/***每5条记录存储一次数据库,实际使用时可以是100条,然后清理链表,方便内存回收*/privatestaticfinalintBATCH_COUNT=100;/***缓存数据*/privateListimportExcelDataList=ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/***每分析一条数据都会调用这个**@paramdata一行值。与{@linkAnalysisContext#readRowHolder()}*@paramcontext*/@Overridepublicvoidinvoke(Testdata,AnalysisContextcontext){log.info("分析到一条数据:{}",JSON.toJSONString(数据));importExcelDataList.add(数据);//当达到BATCH_COUNT时,需要存储一次数据库,防止内存中存储数万条数据,容易OOMif(importExcelDataList.size()>=BATCH_COUNT){saveData();//清理存储importExcelDataList=ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}/***所有数据解析完成,会被调用**@paramcontext*/@OverridepublicvoiddoAfterAllAnalysed(AnalysisContextcontext){//这里也保存数据,保证最后剩下的数据也存储在数据库中saveData();log.info("所有数据解析完成!");}/***加存储数据库*/privatevoidsaveData(){log.info("{}条数据,开始存储数据库!",importExcelDataList.size());testService.saveBatch(importExcelDataList);log.info("数据库保存成功!");}}五、Controller/***@authorwangzhenjun*@date2022/10/2616:51*/@Slf4j@RestController@RequestMapping("/test")publicclassTestController{@AutowiredprivateTestServicetestService;@PostMapping("/import")publicResultimportExcel(@RequestBodyMultipartFilemultipartFile){testService.importExcel(multipartFile);返回结果.成功(“确定”);}}6.Service/***@authorwangzhenjun*@date2022/10/2616:55*/publicinterfaceTestServiceextendsIService{voidimportExcel(MultipartFilemultipartFile);}七、ServiceImpl/***@authorwangzhenjun*@日期2022/10/2616:56*/@ServicepublicclassTestServiceImplextendsServiceImpl实现TestService{@AutowiredprivateImportDataListenerimportDataListener;@SneakyThrows@OverridepublicvoidimportExcel(MultipartFilemultipartFile){InputStreaminputStream=multipartFile.getInputStream();//这里需要指定读取哪个类,然后读取第一个sheet文件流会自动关闭EasyExcel.read(inputStream,Test.class,importDataListener).sheet().doRead();}}八、Mapper/***@authorwangzhenjun*@date2022/10/2617:07*/publicinterfaceTestDbMapperextendsBaseMapper{}九、测试准备Excel数据:postman上传:控制台打印:数据库查看:完美的!!10、小结至此,easyExcel批量导入Excel到数据库就完成了。还有很多需要注意的地方:自定义转换器监听器不要单实例保存数据库,使用批处理版本差距