报错截图
原因:监听器保存数据时,但是没有重置缓存数据,导致读取第二个sheet的时候,缓存里存的数据还包含上一个或多个sheet的数据。每个sheet
读取完毕后调用一次doAfterAllAnalysed
。在doAfterAllAnalysed方法调用批量插入后,需要 清除缓存数据
cacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
1 package com.example.excel.listener; 2 3 import com.alibaba.excel.context.AnalysisContext; 4 import com.alibaba.excel.read.listener.ReadListener; 5 import com.alibaba.excel.util.ListUtils; 6 import com.alibaba.fastjson.JSON; 7 import com.example.excel.entity.ImportExcel; 8 import com.example.excel.service.ImportService; 9 import com.example.excel.service.impl.ImportServiceImpl; 10 import lombok.extern.slf4j.Slf4j; 11 12 import java.util.List; 13 14 /** 15 * <p> 16 * 17 * </p > 18 * 19 * @author Heqq 20 */ 21 // 有个很重要的点 ImportExcelListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 22 @Slf4j 23 public class ImportExcelListener implements ReadListener<ImportExcel> { 24 25 26 /** 27 * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 28 */ 29 private static final int BATCH_COUNT = 100; 30 31 /** 32 * 缓存的数据 33 */ 34 private List<ImportExcel> cacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); 35 36 /** 37 * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 38 */ 39 private ImportService importService; 40 41 /** 42 * 这里是importService,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数 43 */ 44 public ImportExcelListener() { 45 // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数 46 importService = new ImportServiceImpl(); 47 } 48 49 /** 50 * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 51 * 52 * @param importService 53 */ 54 public ImportExcelListener(ImportService importService) { 55 this.importService = importService; 56 } 57 58 /** 59 * 这个每一条数据解析都会来调用 60 * 61 * @param importExcel 62 * @param analysisContext 63 */ 64 @Override 65 public void invoke(ImportExcel importExcel, AnalysisContext analysisContext) { 66 log.info("解析到一条数据:{}", JSON.toJSONString(importExcel)); 67 cacheDataList.add(importExcel); 68 // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM 69 if (cacheDataList.size() >= BATCH_COUNT) { 70 saveData(); 71 // 存储完成清理 list 72 cacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); 73 } 74 } 75 76 /** 77 * 所有数据解析完成了 都会来调用 78 * 79 * @param analysisContext 80 */ 81 @Override 82 public void doAfterAllAnalysed(AnalysisContext analysisContext) { 83 // 这里也要保存数据,确保最后遗留的数据也存储到数据库 84 saveData(); 85 cacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); 86 log.info("所有数据解析完成!"); 87 } 88 89 /** 90 * 加上存储数据库 91 */ 92 public void saveData() { 93 log.info("{}条数据,开始存储数据库!", cacheDataList.size()); 94 importService.saveBatch(cacheDataList); 95 log.info("存储数据成功!"); 96 } 97 }
标签:COUNT,sheet,doReadAll,EasyExcel,excel,cacheDataList,importService,import,com From: https://www.cnblogs.com/-hqq/p/17783701.html