一、前言

今天小编带大家一起整合一下easyExcel,之所以用这个,是因为easyExcel性能比较好,不会报OOM

市面上常见的导入导出Excel分为三种:

  • hutool
  • easyExcel
  • poi

hutooleasyExcel都是对poi的封装,使用起来更加方便!

如果想使用poihutool导出的可以看一下小编的之前写的文章:

使用POI+hutool导入Excel

使用POI把查询到的数据表数据导出到Excel中,一个表一个sheet

导出的话看一下这篇,下面主要以导入来展开介绍!

EasyExcel导出Excel表格到浏览器,并通过Postman测试导出Excel

二、导入依赖

小编这里是3.0.X版本的,版本不同可能导致部分有出入,如果大家版本是3.1.X,可以去官方文档看看有不一样的!

官方文档

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>easyexcel</artifactId>
  4. <version>3.0.5</version>
  5. </dependency>

三、实体类

这里可以自带的转换器:

  • @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
  • LocalDateTimeStringConverter

或者自定义转化器:

实现:implements Converter<T>

具体文档:官方文档

@ExcelProperty参数注意:

这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配

用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据

  1. /**
  2. * @author wangzhenjun
  3. * @date 2022/12/2 15:52
  4. */
  5. @Data
  6. public class Test {
  7. @TableId
  8. private Integer id;
  9. @ExcelProperty(index = 0)
  10. private String name;
  11. @ExcelProperty(index = 1)
  12. private Integer age;
  13. @ExcelProperty(index = 2,converter = LocalDateTimeStringConverter.class)
  14. private LocalDateTime time;
  15. }

四、编写监听器

注意点:

这个监听器一定不要是单例的,被spring管理默认为单例,如果要使用@Component,一定要加上:

@Scope("prototype"),这样在创建完后spring不会进行管理,每次都会是新bean!

不加@Component在导入时要进行new ImportDataListener

小编这里不想new了直接这样写!!如果不想这样,可以使用构造器set进行使用!

BATCH_COUNT :数据阈值,超过了就会清理list,在之前可以进行保存到数据库中,方便内存回收,防治OOM

这里保存到数据库中一般使用批量保存,不要解析到一行就去保存数据库中,这样数据量大会给数据库增加IO,导致挂掉!这里小编使用ServiceImplsaveBatch()方法,也可以自己写一下,像小编这样写,会出现循环依赖,加上@Lazy就行!

  1. /**
  2. * @author wangzhenjun
  3. * @date 2022/12/2 15:38
  4. */
  5. @Slf4j
  6. @Component
  7. // 每次bean都是新的,不要单例
  8. @Scope("prototype")
  9. public class ImportDataListener implements ReadListener<Test> {
  10. @Autowired
  11. @Lazy
  12. private TestService testService;
  13. /**
  14. * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
  15. */
  16. private static final int BATCH_COUNT = 100;
  17. /**
  18. * 缓存的数据
  19. */
  20. private List<Test> importExcelDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
  21. /**
  22. * 这个每一条数据解析都会来调用
  23. *
  24. * @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
  25. * @param context
  26. */
  27. @Override
  28. public void invoke(Test data, AnalysisContext context) {
  29. log.info("解析到一条数据:{}", JSON.toJSONString(data));
  30. importExcelDataList.add(data);
  31. // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
  32. if (importExcelDataList.size() >= BATCH_COUNT) {
  33. saveData();
  34. // 存储完成清理 list
  35. importExcelDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
  36. }
  37. }
  38. /**
  39. * 所有数据解析完成了 都会来调用
  40. *
  41. * @param context
  42. */
  43. @Override
  44. public void doAfterAllAnalysed(AnalysisContext context) {
  45. // 这里也要保存数据,确保最后遗留的数据也存储到数据库
  46. saveData();
  47. log.info("所有数据解析完成!");
  48. }
  49. /**
  50. * 加上存储数据库
  51. */
  52. private void saveData() {
  53. log.info("{}条数据,开始存储数据库!", importExcelDataList.size());
  54. testService.saveBatch(importExcelDataList);
  55. log.info("存储数据库成功!");
  56. }
  57. }

五、Controller

  1. /**
  2. * @author wangzhenjun
  3. * @date 2022/10/26 16:51
  4. */
  5. @Slf4j
  6. @RestController
  7. @RequestMapping("/test")
  8. public class TestController {
  9. @Autowired
  10. private TestService testService;
  11. @PostMapping("/import")
  12. public Result importExcel(@RequestBody MultipartFile multipartFile){
  13. testService.importExcel(multipartFile);
  14. return Result.success("ok");
  15. }
  16. }

六、Service

  1. /**
  2. * @author wangzhenjun
  3. * @date 2022/10/26 16:55
  4. */
  5. public interface TestService extends IService<Test> {
  6. void importExcel(MultipartFile multipartFile);
  7. }

七、ServiceImpl

  1. /**
  2. * @author wangzhenjun
  3. * @date 2022/10/26 16:56
  4. */
  5. @Service
  6. public class TestServiceImpl extends ServiceImpl<TestDbMapper, Test> implements TestService{
  7. @Autowired
  8. private ImportDataListener importDataListener;
  9. @SneakyThrows
  10. @Override
  11. public void importExcel(MultipartFile multipartFile) {
  12. InputStream inputStream = multipartFile.getInputStream();
  13. // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
  14. EasyExcel.read(inputStream, Test.class, importDataListener).sheet().doRead();
  15. }
  16. }

八、Mapper

  1. /**
  2. * @author wangzhenjun
  3. * @date 2022/10/26 17:07
  4. */
  5. public interface TestDbMapper extends BaseMapper<Test> {
  6. }

九、测试

准备Excel数据:



postman上传:



控制台打印:



数据库查看:



完美搞定!!

十、总结

这样就完成了easyExcel批量导入Excel到数据库,还是有很多要注意的点:

  • 自定义转换器
  • 监听器不要单例
  • 保存数据库采用批量
  • 版本差距

如果对你有帮助,还请不要吝啬您的发财小手,你的一键三连是我写作的动力,谢谢大家哈!!


可以看下小编的微信公众号,文章首发看,欢迎关注,一起交流哈!!

SpringBoot+Mybatis-plus整合easyExcel批量导入Excel到数据库+导出Excel的更多相关文章

  1. SpringBoot+Mybatis+MybatisPlus整合实现基本的CRUD操作

    SpringBoot+Mybatis+MybatisPlus整合实现基本的CRUD操作 1> 数据准备 -- 创建测试表 CREATE TABLE `tb_user` ( `id` ) NOT ...

  2. springboot + mybatis + mycat整合

    1.mycat服务 搭建mycat服务并启动,windows安装参照. 系列文章: [Mycat 简介] [Mycat 配置文件server.xml] [Mycat 配置文件schema.xml] [ ...

  3. vue Excel导入,下载Excel模板,导出Excel

    vue  Excel导入,下载Excel模板,导出Excel vue  Excel导入,下载Excel模板 <template> <div style="display: ...

  4. SQLBulkCopy使用实例--读取Excel写入数据库/将 Excel 文件转成 DataTable

    MS SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表可以在不同服务器上). SqlBulkCopy 类允许编写提供类似功能的托管代码解决方 ...

  5. 【数据传输 2】批量导入的前奏:将Excel表中的数据转换为DataTable类型

    导读:我们知道,在数据库中,数据集DataSet是由多张DataTable表组成.所以,如果我们需要将数据从外部导入到数据库中,那么要做的很重要的一步是将这些数据转换为数据库可以接受的结构.今天在用S ...

  6. 海量数据Excel报表利器——EasyExcel(一 利用反射机制导出Excel)

    EasyExcel 写入(导出) 互联网的精髓就是共享,可以共享技术.共享经验.共享情感.共享快乐~ 很多年前就有这个想法了,从事IT行业时间也不短了,应该把自己工作和业余所学习的东西记录并分享出来, ...

  7. C# NPOI导出Excel和EPPlus导出Excel比较

    系统中经常会使用导出Excel的功能. 之前使用的是NPOI,但是导出数据行数多就报内存溢出. 最近看到EPPlus可以用来导出Excel,就自己测了下两者导出上的差异. NPIO官网地址:http: ...

  8. PHP从数据库导出EXCEL文件

    参考博客链接:http://www.cnblogs.com/huangcong/p/3687665.html 我的程序代码 原生导出Excel文件 <?phpheader('Content-ty ...

  9. Powerdesigner 导出Excel格式数据字典 导出Excel格式文件

    版权声明:本文为博主原创文章,转载请注明出处; 网上我也看到了很多的Powerdesigner 导出方法,因为Powerdesigner 提供了部分VBA功能,所以让我用代码导出Excel格式文件得以 ...

  10. poi操作oracle数据库导出excel文件2

    package com.test; import java.io.File;  import java.io.FileInputStream;  import java.io.FileNotFound ...

随机推荐

  1. __g is not defined

    新手小白学习小程序开发遇到的问题以及解决方法 文章目录 1.出现的问题 2.解决的方法 1.出现的问题 2.解决的方法 删除app.json中的 "lazyCodeLoading" ...

  2. 重新整理 .net core 实践篇 ———— linux 上线篇 [外篇]

    前言 简单整理一个linux 简单上线. 这个是该系列的外篇,该系列继续更新.献给刚学的人. 正文 安装实例 dotnet new webapp -n AspNetCoreDemo -o firstw ...

  3. c语言求输入的任一整数的各位数之和

    c语言求解代码: # include<stdio.h> int main(void){ int a,i=0,sum=0; scanf("%d",&a); if( ...

  4. [Android开发学iOS系列] Auto Layout

    [Android开发学iOS系列] Auto Layout 内容: 介绍什么是Auto Layout. 基本使用方法 在代码中写约束的方法 Auto Layout的原理 尺寸和优先级 Auto Lay ...

  5. Python基础之模块:1、模块的导入和使用

    目录 一.模块 1.简介 2.模块的表现形式 二.模块的分类 1.自定义模块 2.内置模块 3.第三方模块 三.导入模块的句式 学前须知: 1.import句式 2.from...import...句 ...

  6. pod(八):pod的调度——将 Pod 指派给节点

    目录 一.系统环境 二.前言 三.pod的调度 3.1 pod的调度概述 3.2 pod自动调度 3.2.1 创建3个主机端口为80的pod 3.3 使用nodeName 字段指定pod运行在哪个节点 ...

  7. Goland环境中Go module配置

    [现象] 从go vendor切换到go module之后,import包解析有问题.如下所示: 对应的go modules也没解析出来 [原因] 有两点原因: goland中go module配置存 ...

  8. 超精准!AI 结合邮件内容与附件的意图理解与分类!⛵

    作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 TensorFlow 实战系列:https://www.showmeai ...

  9. Kubernetes_Deployment全解析(无状态的Pod)

    前言 一.创建Deployment 1.1 创建Deployment apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy ...

  10. mysql 在连接表中的要点

    思路:分析需求,分析字段来自哪些表 (连接查询)            确定使用哪种连接查询?  确定交叉点(这两个表中哪些数据是相同的)            判断条件 such as  学生表中的 ...