SpringBoot+EasyExcel+Mybatis-plus实现通用Excel数据批量导入

Hi,大家好,我是抢老婆酸奶的小肥仔。

在我们日常开发中,有个功能几乎是没办法绕开的,那就是Excel数据的导入。当然也有很多工具支持导入导出,比如:Apache POI,jxl,由于Apache POI在加载大量数据时会出现OOM,因此阿里在其基础上进行了封装形成了EasyExcel,这便是我们今天要说的主角。

1、EasyExcel简介

官网:https://easyexcel.opensource.alibaba.com/

按照官网介绍,EasyExcel具有以下特点:

  1. 基于java实现的
  2. 快捷、简洁、解决大文件内存溢出(即OOM)
  3. 不用考虑性能、内存等因素情况下,快速完成Excel的读、写等功能。

从简介中,知道使用EasyExcel操作Excel时,我们只需要关注业务本身即可。

2、程序实现

上述我们稍稍简介了下EasyExcel,接下来我们来看看怎样使用。

引入依赖

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>3.3.2</version>
</dependency>

2.1 读取Excel

按照官网给出的例子,一共有4种读取Excel写法,通过官网的例子来看,其实所有例子都是要以ReadListener<T> 为基础。我们以官网提供的方法一(PageReadListener)为例来说下EasyExcel读取的实现。

EasyExcel.read(fileName, DemoData.class, new PageReadListener<DemoData>(dataList -> {
   
    for (DemoData demoData : dataList) {
   
        log.info("读取到一条数据{}", JSON.toJSONString(demoData));
    }
}),1000).sheet().doRead();

这种方法直接使用了PageReadListener监听器,我们来看看PageReadListener源码:

public class PageReadListener<T> implements ReadListener<T> {
   
    public static int BATCH_COUNT = 100;
    private List<T> cachedDataList;
    private final Consumer<List<T>> consumer;
    private final int batchCount;

    public PageReadListener(Consumer<List<T>> consumer) {
   
        this(consumer, BATCH_COUNT);
    }

    public PageReadListener(Consumer<List<T>> consumer, int batchCount) {
   
        this.cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        this.consumer = consumer;
        this.batchCount = batchCount;
    }

    public void invoke(T data, AnalysisContext context) {
   
        this.cachedDataList.add(data);
        if (this.cachedDataList.size() >= this.batchCount) {
   
            this.consumer.accept(this.cachedDataList);
            this.cachedDataList = ListUtils.newArrayListWithExpectedSize(this.batchCount);
        }

    }

    public void doAfterAllAnalysed(AnalysisContext context) {
   
        if (CollectionUtils.isNotEmpty(this.cachedDataList)) {
   
            this.consumer.accept(this.cachedDataList);
        }

    }
}

在PageReadListener中给了两个构造方法,两者唯一区别就是一个采用了默认的读取条数,一个采用了用户自定义的条数。

在源码中还有两个方法:invokedoAfterAllAnalysed,他们都是实现ReadListener接口里面定义的方法。

invoke:表示每解析完一条数据就会调用该初始方法,因此很多条件筛选或业务我们可以放在里面实现。

doAfterAllAnalysed:表示每解析完一个sheet页后调用该方法。

从源码中知道,invoke方法中当数组的长度大于等于设置的长度时,则执Consumer,执行完成后在进行初始化集合;doAfterAllAnalysed方法中在获取完数据后,判断当前集合时候还有数据,有的话则执行Consumer。

2.2 整合Mybutis-plus

我们通过方法一了解了PageReadListener的实现过程,那么我们也可以仿照PageReadListener、结合Mybatis-plus来实现一个通用批量导入的功能。

我们来简单引入Mybatis-plus。

1、引入依赖

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.5.3</version>
</dependency>

2、Mybatis-plus配置

/**
 * @author: jiangjs
 * @description: mybatis-plus配置
 * @date: 2023/10/20 15:16
 **/
@Configuration
@MapperScan(value = "com.**.mapper.**")
public class MybatisPlusConfig {
   
}

3、数据库开启批量插入

在Mysql批量插入数据时,我们一般采用insert ino table (xxx,xxxx) valus (11,22),(33,44),这种方式减少了数据库的连接,提高插入效率,而mybatis这样执行批处理需要在数据库url配置上添加rewriteBatchedStatements=true,进行批处理开启。

url: jdbc:mysql://127.0.0.1:3308/xxxxx?characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=false&useUnicode=true&rewriteBatchedStatements=true

上述准备工作做好后,我们开始编写代码。

2.2.1

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值