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();}
}

运行如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/375103.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PMP–知识卡片--项目管理五大过程组

记忆 五大“项目管理过程组”&#xff1a;启动&#xff0c;规划&#xff0c;执行&#xff0c;监控&#xff0c;收尾 五个领域&#xff0c;十个字&#xff0c;形象理解&#xff0c;理解逻辑&#xff1a;先启动→再规划→再执行→要监控→最后收尾 定义 经典项目管理场景将项目…

“闭门造车”之多模态思路浅谈:自回归学习与生成

©PaperWeekly 原创 作者 | 苏剑林 单位 | 科学空间 研究方向 | NLP、神经网络 这篇文章我们继续来闭门造车&#xff0c;分享一下笔者最近对多模态学习的一些新理解。 在前文《“闭门造车”之多模态思路浅谈&#xff1a;无损》中&#xff0c;我们强调了无损输入对于理想的…

mac生成.dmg压缩镜像文件

mac生成.dmg压缩镜像文件 背景准备内容步骤1&#xff0c;找一个文件夹2&#xff0c;制作application替身1&#xff0c;终端方式2&#xff0c;黄金右手方式 3&#xff0c;.app文件放入文件夹4&#xff0c;制作.dmg压缩镜像文件5&#xff0c;安装.dmg 总结 背景 为绕开App Store…

Go语言---并发编程之channel(双channel,单channel)以及应用实例(生产者消费者、打印机模型)

Channel goroutine 运行在相同的地址空间&#xff0c;因此访问共享内存必须做好同步。goroutine 通过通信来共享内存&#xff0c;而不是其享内存来通信。 引用类型 channel 是CSP 模式的具体实现,用于多个 goroutine 通讯。其内部实现了同步&#xff0c;确保并发安全。 chan…

FastAPI 学习之路(三十四)数据库多表操作

之前我们分享的是基于单个表的数据库表的操作&#xff0c;我们在设计数据库的时候也设计了跨表&#xff0c;我们可以看下数据库的设计 class User(Base):__tablename__ "users"id Column(Integer, primary_keyTrue, indexTrue)email Column(String(10), uniqueTr…

Python:Python基础知识(注释、命名、数据类型、运算符)

.注释 Python有两种注释方法&#xff1a;单行注释和多行注释。单行注释以#开头&#xff0c;多行注释以三个单引号 或三个双引号 """ 开头和结尾。 2.命名规则 命名规则: 大小写字母、数字、下划线和汉字等字符及组合&#xff1b; 注意事项: 大小写敏感、首…

ESP32FreeRTOS开发笔记:1.双核并行

ESP32 的 Arduino 框架内部集成了 FreeRTOS&#xff0c;允许开发者利用其多任务处理功能。在代码中&#xff0c;xTaskCreatePinnedToCore 函数是 FreeRTOS 提供的 API&#xff0c;用于创建任务并指定任务在哪个核心上运行。 FreeRTOS 是一个流行的实时操作系统内核&#xff0c;…

JavaSE学习笔记之内部类、枚举类和基本类型包装类

今天我们继续复习Java相关的知识&#xff0c;和大家分享有关内部类等方面的知识&#xff0c;希望大家喜欢。 目录​​​​​​​ 内部类 成员内部类 ​编辑 静态内部类 局部内部类 匿名内部类 枚举类 定义方法 基本类型包装类 自动装箱和拆箱 内部类 成员内部类 成…

《Windows API每日一练》9.1.5 自定义资源

自定义资源&#xff08;Custom Resources&#xff09;是在 Windows 程序中使用的一种资源类型&#xff0c;用于存储应用程序特定的数据、图像、音频、二进制文件等。通过自定义资源&#xff0c;开发者可以将应用程序所需的各种资源文件集中管理和存储&#xff0c;便于在程序中访…

从人工巡检到智能预警:视频AI智能监控技术在水库/河湖/水利防汛抗洪中的应用

一、背景需求分析 近日&#xff0c;我国多省市遭遇连日暴雨&#xff0c;导致水库、湖泊、河道等水域水位暴涨&#xff0c;城市内涝频发。随着夏季汛期的到来&#xff0c;降雨天气频繁&#xff0c;水利安全管理面临严峻挑战。为保障水库安全、预防和减少洪涝灾害&#xff0c;采…

文档去重(TF-IDF,MinHash, SimHash)

2个doc有些相似有些不相似&#xff0c;如何衡量这个相似度&#xff1b; 直接用Jaccard距离&#xff0c;计算量太大 TF-IDF: TF*IDF TF&#xff1a;该词在该文档中的出现次数&#xff0c; IDF&#xff1a;该词在所有文档中的多少个文档出现是DF&#xff0c;lg(N/(1DF)) MinHash …

windows上修改redis端口号

概况 redis是一个开源的内存数据结构存储系统&#xff0c;常用做数据库、缓存和消息代理。默认的端口号为6379 更改redis端口号步骤如下 先停止redis服务 redis-cli shutdowm 打开redis配置文件 在redis安装目录下&#xff0c;即redis.windows.conf文件。 port 6396 然后…

i18n、L10n、G11N 和 T9N 的含义

注&#xff1a;机翻&#xff0c;未校对。 Looking into localization for the first time can be terrifying, if only due to all of the abbreviations. But the meaning of i18n, L10n, G11N, and T9N, are all very easy to understand. 第一次研究本地化可能会很可怕&…

NI VST 毫米波测试仪器创新

目录 概览​从UHF至V频段的频率覆盖范围&#xff1a;54 GHz远程测量模块​PXIe-5842&#xff1a;VST架构的扩展54 GHz扩频PXIe-5842功能​​宽频覆盖范围​IF和毫米波测试端口可满足多频带需求​高达2 GHz瞬时带宽误差矢量幅度测量性能相位相干同步基于PXI平台集成多种仪器 互补…

Jmeter多用户登录操作实战

在使用Jmeter性能测试时,首先要解决的问题恐怕就会并发压测和多用登录的问题.今天就一篇文章讲清楚这两个问题的解决方案: 一.多并发压测如何配置线程? &#xff08;1&#xff09;同时并发&#xff1a;设置线程组、执行时间、循环次数&#xff0c;这种方式可以控制接口请求的…

01表操作/数类型定义

文章目录 表操作表的创建列的类型定义整数类型浮点类型和定点数类型日期和时间类型 表操作 表的创建 列的类型定义 整数类型 浮点类型和定点数类型 日期和时间类型

探索【Python面向对象】编程:新时代的高级编程范式详解

目录 1. 面向对象编程概念&#xff08;OOP&#xff09; 1.1 什么是类和对象&#xff1f; 1.2 类的定义 1.3 类和对象的关系 1.4 小李的理解 2. 抽象 2.1 抽象的概念 2.2 抽象类和方法 2.3 小李的理解 3. 类和实例 3.1 类的定义和实例化 3.2 类的属性和方法 3.3 小…

【Android】基于 LocationManager 原生实现定位打卡

目录 前言一、实现效果二、定位原理三、具体实现1. 获取权限2. 页面绘制3. 获取经纬度4. 方法调用5. 坐标转换6. 距离计算7. 完整代码 前言 最近公司有个新需求&#xff0c;想要用定位进行考勤打卡&#xff0c;在距离打卡地一定范围内才可以进行打卡。本文将借鉴 RxTool 的 Rx…

【安全设备】入侵检测

一、什么是入侵检测 入侵检测是一种网络安全技术&#xff0c;用于监测和识别对计算机系统或网络的恶意使用行为或未经授权的访问。入侵检测系统&#xff08;IDS&#xff09;是实现这一目标的技术手段&#xff0c;其主要目的是确保计算机系统的安全&#xff0c;通过及时发现并报…

蜂窝互联网接入:连接世界的无缝体验

通过Wi—Fi&#xff0c;人们可以方便地接入互联网&#xff0c;但无线局域网的覆盖范围通常只有10&#xff5e;100m。当我们携带笔记本电脑在外面四处移动时&#xff0c;并不是在所有地方都能找到可接入互联网的Wi—Fi热点&#xff0c;这时候蜂窝移动通信系统可以为我们提供广域…