当前位置: 首页 > news >正文

EasyExcel批量读取Excel文件数据导入到MySQL表中

1、EasyExcel简介

官网:EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网

2、代码实战

首先引入jar包

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

2.1 读取Excel

2.1.1  使用PageReadListener

这种方式代码简洁,通俗易懂,直接看示例:

 public void readExcelFile2(MultipartFile file) {AtomicInteger count = new AtomicInteger(0);try {int batch = 10;EasyExcel.read(file.getInputStream(), SharePathApproveModule.class, new PageReadListener<SharePathApproveModule>(list -> {System.out.println("已完成" + list.size() + "条数据读取...");for (SharePathApproveModule module : list) {System.out.println("读取到" + count.incrementAndGet() + "条数据=>" + JSONObject.toJSONString(module));}//批量写入//sharePathApproveMapper.insertBatch(list);}, batch)).sheet(0).doRead();//sheetNo参数不传默认0,读取第一个sheet;填0也是读取第1个sheet;填1即读取第2个sheet} catch (Exception e) {log.error("读取Excel数据异常,", e);}}

这种方式是直接使用了PageReadListener监听器,有兴趣的同学可以自行解读PageReadListener源码,这里我只把源码粘贴出来,本文主要讲实战,就不过多说PageReadListener。

import java.util.List;
import java.util.function.Consumer;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.util.ListUtils;import org.apache.commons.collections4.CollectionUtils;/*** page read listener** @author Jiaju Zhuang*/
public class PageReadListener<T> implements ReadListener<T> {/*** Default single handle the amount of data*/public static int BATCH_COUNT = 100;/*** Temporary storage of data*/private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);/*** consumer*/private final Consumer<List<T>> consumer;/*** Single handle the amount of data*/private final int batchCount;public PageReadListener(Consumer<List<T>> consumer) {this(consumer, BATCH_COUNT);}public PageReadListener(Consumer<List<T>> consumer, int batchCount) {this.consumer = consumer;this.batchCount = batchCount;}@Overridepublic void invoke(T data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= batchCount) {consumer.accept(cachedDataList);cachedDataList = ListUtils.newArrayListWithExpectedSize(batchCount);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {if (CollectionUtils.isNotEmpty(cachedDataList)) {consumer.accept(cachedDataList);}}}

 简单的说一下PageReadListener监听器的两个方法:invoke和doAfterAllAnalysed;他们都是实现ReadListener接口里面定义的方法。

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

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

从源码中知道,invoke()中当数组的长度大于等于设置的长度时,则执Consumer,执行完成后在进行初始化集合;

doAfterAllAnalysed()中在获取完数据后,判断当前集合时候还有数据,有的话则执行Consumer。

2.1.2  自定义监听器

我们可以通过继承AnalysisEventListener类来自定义监听器,重新里面的invoke和doAfterAllAnalysed方法。

首先,新建一个Module

/*** @description* @date 2024-07-10 18:02**/
@Data
public class ShareModule {@ExcelProperty(value = "share路径", index = 0)@ColumnWidth(value = 10)private String sharePath;@ExcelProperty(value = "权限", index = 1)@ColumnWidth(value = 10)private String access;@ExcelProperty(value = "组名", index = 2)@ColumnWidth(value = 10)private String groupCn;@ExcelProperty(value = "历史申请人", index = 3)@ColumnWidth(value = 20)private String applicants;
}

接着,定义Mapper和Mapper.xml,这里我们只写一个批量插入的方法,使用

insert into table_name(column1,column2,column3) values(x,x,x),(x,x,x),.....

这种方式减少了数据库的连接,提高插入效率,而mybatis这样执行批处理需要在数据库url配置上添加rewriteBatchedStatements=true,进行批处理开启。

public interface ShareMapper {int insertBatch(@Param("shareModules")List<ShareModule> shareModules);int clearTableData();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.demo.mapper.ShareMapper"><insert id="insertBatch">INSERT INTO share_path_approve (share_path, access, group_cn, applicants) VALUES<foreach collection="shareModules" index="index" item="po" separator=",">(#{po.sharePath}, #{po.access}, #{po.groupCn}, #{po.applicants})</foreach></insert><update id="clearTableData">truncate table share_path_approve</update></mapper>

然后,就是自定义监听器,配将这个监听器交给Spring容器

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.wangpeng.mapper.SharePathApproveMapper;
import com.example.wangpeng.po.module.SharePathApproveModule;
import lombok.extern.slf4j.Slf4j;import java.util.ArrayList;
import java.util.List;/*** @description share auto* @date 2024-07-10 10:30*/
@Slf4j
public class ShareListener extends AnalysisEventListener<ShareModule> {private List<ShareModule> cacheData = new ArrayList<>();private static final int BATCH_COUNT = 8;private final ShareMapper shareMapper;public SharePathApproveListener(ShareMapper shareMapper) {this.shareMapper= shareMapper;}@Overridepublic void invoke(ShareModule shareModule, AnalysisContext analysisContext) {cacheData.add(shareModule);if (cacheData.size() >= BATCH_COUNT) {log.info("保存数据--share auto-----{}条", cacheData.size());saveData();// 可以清理缓存数据cacheData = new ArrayList<>();}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {// 处理最后未达到8条数据的插入if (!cacheData.isEmpty()) {log.info("保存数据--share auto-----{}条", cacheData.size());saveData();}}private void saveData() {// 这里可以使用MyBatis的批量插入方法shareMapper.insertBatch(cacheData);}
}
import com.example.wangpeng.excel.SharePathApproveListener;
import com.example.wangpeng.mapper.SharePathApproveMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @description* @date 2024-07-10 18:17*/
@Configuration
public class EasyExcelConfig {@Beanpublic ShareListener shareListener(ShareMapper shareMapper) {return new shareListener(shareMapper);}
}

最后一步,就是编写Service和实现类、控制层接口代码

public interface ExcelService {ResponseResult<?> importExcel(MultipartFile file, Integer type);}
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.excel.ShareListener;
import com.example.demo.mapper.ShareMapper;
import com.example.demo.po.module.ShareModule;
import com.example.demo.response.ResponseResult;
import com.example.demo.service.ExcelService;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;/*** @description* @date 2024-06-03 15:57*/
@Log4j
@Service
public class ExcelServiceImpl implements ExcelService {@Autowiredprivate SharePathApproveMapper sharePathApproveMapper;@Overridepublic ResponseResult<?> importExcel(MultipartFile file, Integer type) {try (InputStream inputStream = file.getInputStream()) {if (0 == type) {//全量覆盖sharePathApproveMapper.clearTableData();}  //增量插入EasyExcel.read(inputStream, ShareModule.class, new ShareListener(shareMapper)).sheet().doRead();return ResponseResult.success();} catch (Exception e) {log.info("ShareExcel并解析 异常!", e);return ResponseResult.fail(e.getMessage());}}
}

@RestController
@RequestMapping(value = "/excel")
public class ExcelController {@Autowiredprivate ExcelService excelService;@PostMapping(value = "/import")public ResponseResult<String> excelFile2(@RequestBody MultipartFile file, Integer type) {excelService.importExcel(file, type);return ResponseResult.success();}
}

运行如下:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 二分查找中while的判断条件
  • 11.FreeRTOS_事件组
  • 使用Python和MediaPipe实现手势虚拟鼠标控制
  • 自动驾驶论文总结
  • SQL 索引
  • PyTorch DataLoader 学习
  • 2024前端面试真题【CSS篇】
  • 【数据结构】线性表----队列详解
  • 【2024_CUMCM】时间序列3-一元时间序列分析的模型
  • Spring容器加载Bean和JVM加载类
  • 【网络安全】Oracle:SSRF获取元数据
  • Python编程学习笔记(3)--- 操作列表
  • C++的入门基础(二)
  • vue 画二维码及长按保存
  • 基于TCP的在线词典系统(分阶段实现)(阻塞io和多路io复用(select)实现)
  • [译] 怎样写一个基础的编译器
  • 2018一半小结一波
  • AHK 中 = 和 == 等比较运算符的用法
  • Angular Elements 及其运作原理
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • fetch 从初识到应用
  • java小心机(3)| 浅析finalize()
  • js对象的深浅拷贝
  • miaov-React 最佳入门
  • Next.js之基础概念(二)
  • Promise面试题,控制异步流程
  • select2 取值 遍历 设置默认值
  • Selenium实战教程系列(二)---元素定位
  • zookeeper系列(七)实战分布式命名服务
  • 阿里云应用高可用服务公测发布
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端相关框架总和
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 微信小程序填坑清单
  • 协程
  • 用 Swift 编写面向协议的视图
  • 源码安装memcached和php memcache扩展
  • 运行时添加log4j2的appender
  • 函数计算新功能-----支持C#函数
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​低代码平台的核心价值与优势
  • # C++之functional库用法整理
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (rabbitmq的高级特性)消息可靠性
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (算法设计与分析)第一章算法概述-习题
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法