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.mzph.cn/news/871528.shtml

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

相关文章

【计算机毕业设计】基于Springboot的智能推荐卫生健康系统【源码+lw+部署文档】

包含论文源码的压缩包较大,请私信或者加我的绿色小软件获取 免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,…

智慧校园缴费管理-缴费项目类型功能概述

智慧校园的缴费管理系统&#xff0c;以缴费项目类型为核心功能之一&#xff0c;精细划分并优化了各类缴费流程&#xff0c;为学生和家长带来更为直观、便捷的财务管理体验。这一功能通过整合校园内广泛的费用类别&#xff0c;确保每一笔费用都能准确、高效地处理&#xff0c;体…

中介子方程五十八

XXFXXaXnXaXXαXLXyXXWXuXeXKXXiXyXΣXXΣXXVXuXhXXWXηXXiXhXXpXiXXpXXbXXiXOXWXyXkXXeXpXXOXXiXnXiXXOXXpXeXXkXyXWXOXiXXbXXpXXiXpXXhXiXXηXWXXhXuXVXXΣXXΣXyXiXXKXeXuXWXXyXLXαXXaXnXaXXFXXaXnXaXXαXLXyXXWXuXeXKXXiXyXΣXXΣXXVXuXhXXWXηXXiXhXXpXiXXpXXbXXiXOXWXyX…

Provider(2)- SourceAudioBufferProvider

SourceAudioBufferProvider 从Source源端出来的数据&#xff0c;通常是来自于应用层&#xff0c;但没有与应用层直接连接&#xff0c;通过MonoPipe相关类连接&#xff0c;其SourceAudioBufferProvider和MonoPipe相关类的包含关系图如下&#xff1a; 如上图&#xff0c;Sourc…

11计算机视觉—语义分割与转置卷积

目录 1.语义分割应用语义分割和实例分割2.语义分割数据集:Pascal VOC2012 语义分割数据集预处理数据:我们使用图像增广中的随机裁剪,裁剪输入图像和标签的相同区域。3.转置卷积 上采样填充、步幅和多通道填充步幅多通道转置卷积是一种卷积:重新排列输入和核转置卷积是一种卷…

Java高级重点知识点-22-缓冲流、转换流、序列化流、打印流

文章目录 缓冲流字节缓冲流字符缓冲流 转换流InputStreamReader类OutputStreamWriter类 序列化ObjectOutputStream类ObjectInputStream类 打印流 缓冲流 缓冲流,也叫高效流&#xff0c;是对4个基本的 FileXxx 流的增强&#xff0c;所以也是4个流 基本原理&#xff1a; 缓冲流的…

ES13的4个改革性新特性

1、类字段声明 在 ES13 之前,类字段只能在构造函数中声明, ES13 消除了这个限制 // 之前 class Car {constructor() {this.color = blue;this.age = 2

C++ | Leetcode C++题解之第232题用栈实现队列

题目&#xff1a; 题解&#xff1a; class MyQueue { private:stack<int> inStack, outStack;void in2out() {while (!inStack.empty()) {outStack.push(inStack.top());inStack.pop();}}public:MyQueue() {}void push(int x) {inStack.push(x);}int pop() {if (outStac…

linux_进程周边知识——理解冯诺依曼体系结构

前言&#xff1a; 本篇内容是为了让友友们较好地理解进程的概念&#xff0c; 而在真正了解进行概念之前&#xff0c; 要先了解一下冯诺依曼体系结构。 所以博主会先对冯诺伊曼体系结构进行解释&#xff0c; 然后再讲解进程的概念。 ps&#xff1a; 本篇内容适合了解一些linux指…

大模型时代,还需要跨端framework吗?

跨端 在我近十年的大前端从业经验中&#xff0c;有一半是在和flutter/rn打交道。虽然&#xff0c;flutter和rn官方和社区已经在非常努力的优化、填坑了&#xff0c;但是这两者的坑还是远远高于原生开发。 但是&#xff0c;在锁表的大周期下&#xff0c;华为带着鸿蒙来了&#…

基于复旦微JFMQL100TAI的全国产化FPGA+AI人工智能异构计算平台,兼容XC7Z045-2FFG900I

基于上海复旦微电子FMQL45T900的全国产化ARM核心板。该核心板将复旦微的FMQL45T900&#xff08;与XILINX的XC7Z045-2FFG900I兼容&#xff09;的最小系统集成在了一个87*117mm的核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&#xff0c;能够快速的搭建起…

springboot大学校园二手书交易APP

摘 要 在数字化与移动互联网迅猛发展的今天&#xff0c;人们对于图书的需求与消费方式也在悄然改变。为了满足广大读者对图书的热爱与追求&#xff0c;我们倾力打造了一款基于Android平台的图书交易APP。这款APP不仅汇聚了海量的图书资源&#xff0c;提供了便捷的交易平台&…

【产品经理】WMS多仓调拨转移说明

对于仓储管理来说&#xff0c;越来越多企业开始应用WMS进行系统化的管理&#xff0c;以提升仓库的作业效率。本文作者从业务流程和基础功能两个方面展开介绍&#xff0c;希望对你有帮助。 一、业务流程 。在线下业务流程拓展&#xff0c;仓库不断增多的过程中&#xff0c;由于…

vscode终端(控制台打印乱码)

乱码出现的两种可能&#xff08;重点是下面标题2&#xff09; 1、文件中的汉字本来就是乱码&#xff0c;输出到控制台(终端)那就当然是乱码 在vscode中设置文件的编码格式为UTF-8&#xff0c; 2、输出到控制台(终端)之前的汉字不是乱码&#xff0c;针对此种情况如下设置 原因…

k8s资源管理中request和limit的区别

在 Kubernetes&#xff08;K8s&#xff09;中&#xff0c;request和limit是两个重要的概念&#xff0c;用于控制和管理容器的资源使用。 Request&#xff08;请求&#xff09;&#xff1a; request定义了容器启动时需要保证的最小资源量。这表示Kubernetes在调度Pod到节点时&a…

用“坦克”来更形象的理解面向对象编程的类的访问权限

我们可以 把私有变量比喻为坦克里面的人&#xff0c;把公共方法比作是驾驶室的门&#xff0c;然后把其他的代码比喻为 子弹&#xff0c;坦克就是一个封装&#xff0c;来保护人 这个比喻非常形象&#xff0c;它很好地解释了封装的概念和它在面向对象编程中的作用。下面我将根据你…

如何隐藏 Ubuntu 顶部状态栏

如何隐藏 Ubuntu 顶部状态栏 Chapter1 如何隐藏 Ubuntu 顶部状态栏Chapter2 Ubuntu增大屏幕可用面积之——自动隐藏顶部状态栏Chapter3 Ubuntu18.04隐藏顶栏与侧栏 Chapter1 如何隐藏 Ubuntu 顶部状态栏 https://www.sysgeek.cn/hide-top-bar-ubuntu/ 准备工作&#xff1a;安…

GuLi商城-商品服务-API-品牌管理-JSR303分组校验

注解:@Validated 实体类: package com.nanjing.gulimall.product.entity;import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.nanjing.common.valid.ListValue; import com.nanjing.common.valid.Updat…

【Python学习笔记】Optuna + Transformer B站视频实践

【Python学习笔记】Optuna Transformer 实践 背景前摇&#xff08;省流可不看&#xff09;&#xff1a; 之前以泰坦尼克号数据集为案例&#xff0c;学习了Optuna的基本操作&#xff0c;为了进一步巩固知识和便于包装简历&#xff0c;决定找个唬人一点的项目练练手。 ————…

conda激活的虚拟环境的python版本不对应

这个大坑&#xff0c;要看看虚拟环境下envs下有没有bin文件夹 python -Vecho $PATH镜像源的问题&#xff0c;参考