diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java index 54218355..9defb5f3 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/UploadDataListener.java @@ -8,14 +8,19 @@ import com.alibaba.excel.util.ListUtils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; /** * 模板的读取类 * * @author Jiaju Zhuang */ -// 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 @Slf4j +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class UploadDataListener implements ReadListener { /** * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 @@ -25,22 +30,9 @@ public class UploadDataListener implements ReadListener { /** * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 */ + @Autowired private UploadDAO uploadDAO; - public UploadDataListener() { - // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数 - uploadDAO = new UploadDAO(); - } - - /** - * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 - * - * @param uploadDAO - */ - public UploadDataListener(UploadDAO uploadDAO) { - this.uploadDAO = uploadDAO; - } - /** * 这个每一条数据解析都会来调用 * @@ -54,8 +46,6 @@ public class UploadDataListener implements ReadListener { // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (cachedDataList.size() >= BATCH_COUNT) { saveData(); - // 存储完成清理 list - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); } } @@ -67,7 +57,9 @@ public class UploadDataListener implements ReadListener { @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 - saveData(); + if (cachedDataList.size() > 0) { + saveData(); + } log.info("所有数据解析完成!"); } @@ -77,6 +69,19 @@ public class UploadDataListener implements ReadListener { private void saveData() { log.info("{}条数据,开始存储数据库!", cachedDataList.size()); uploadDAO.save(cachedDataList); + cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); log.info("存储数据库成功!"); } + + /** + * 保证在invoke解析数据或者写入数据库发生异常都能将cachedDataList清理 + * @param exception + * @param context + * @throws Exception + */ + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception { + cachedDataList.clear(); + ReadListener.super.onException(exception, context); + } } diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java index 0260534f..b3c3283c 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java @@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; @@ -29,7 +30,7 @@ import org.springframework.web.multipart.MultipartFile; public class WebTest { @Autowired - private UploadDAO uploadDAO; + private UploadDataListener uploadDataListener; /** * 文件下载(失败了会返回一个有部分数据的Excel) @@ -93,7 +94,7 @@ public class WebTest { @PostMapping("upload") @ResponseBody public String upload(MultipartFile file) throws IOException { - EasyExcel.read(file.getInputStream(), UploadData.class, new UploadDataListener(uploadDAO)).sheet().doRead(); + EasyExcel.read(file.getInputStream(), UploadData.class, uploadDataListener).sheet().doRead(); return "success"; }