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

news2024/9/9 4:44:41

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

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

    @Override
    public 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;
    }


    @Override
    public void invoke(ShareModule shareModule, AnalysisContext analysisContext) {
        cacheData.add(shareModule);
        if (cacheData.size() >= BATCH_COUNT) {
            log.info("保存数据--share auto-----{}条", cacheData.size());
            saveData();
            // 可以清理缓存数据
            cacheData = new ArrayList<>();
        }
    }

    @Override
    public 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 {

    @Bean
    public 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 {

    @Autowired
    private SharePathApproveMapper sharePathApproveMapper;


    @Override
    public 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 {

    @Autowired
    private ExcelService excelService;

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

运行如下:

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

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

相关文章

Facebook的未来蓝图:从元宇宙到虚拟现实的跨越

随着科技的不断演进和社会的数字化转型&#xff0c;虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;作为下一代计算平台正逐渐走进人们的视野。作为全球领先的科技公司之一&#xff0c;Facebook正在积极探索并推动这一领域的发展&#xff0c;以实现其…

【linux】服务器卸载cuda

【linux】服务器卸载cuda 文章目录 【linux】服务器卸载cuda1、查找已安装的 CUDA 包&#xff1a;2、卸载 CUDA&#xff1a;3、删除残留文件4、更新系统的包索引&#xff1a;5、检查是否卸载干净&#xff1a; 1、查找已安装的 CUDA 包&#xff1a; dpkg -l | grep cuda2、卸载…

python用selenium网页模拟时无法定位元素解决方法1

进行网页模拟时&#xff0c;有时我们明明可以复制出元素的xpath&#xff0c;但是用selenium的xpath click无法点击到元素。这种情况有几种原因&#xff0c;本文写其中一种——iframe 比如下图网址&#xff0c;第二行出现iframe&#xff0c;则往下的行内元素都会定位不到&#…

07-7.5.1 散列表的基本概念

&#x1f44b; Hi, I’m Beast Cheng &#x1f440; I’m interested in photography, hiking, landscape… &#x1f331; I’m currently learning python, javascript, kotlin… &#x1f4eb; How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以…

并查集+链表,CF 1131F - Asya And Kittens

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1131F - Asya And Kittens 二、解题报告 1、思路分析 本质是拼积木游戏 初始有n块积木&#xff0c;每次两块首尾拼成一块就行&#xff0c;拼接n - 1 次最后会得到一个大积木&#xff0c;我们从左往右输出组…

UDP网络通信(发送端+接收端)实例 —— Python

简介 在网络通信编程中&#xff0c;用的最多的就是UDP和TCP通信了&#xff0c;原理这里就不分析了&#xff0c;网上介绍也很多&#xff0c;这里简单列举一下各自的优缺点和使用场景 通信方式优点缺点适用场景UDP及时性好&#xff0c;快速视网络情况&#xff0c;存在丢包 与嵌入…

dolphinScheduler + hive + datax报错记录

1、参数错误 报错信息 [INFO] 2024-04-11 06:43:18.386 - [taskAppIdTASK-29-3301-84461]:[498] - after replace sql , preparing : insertoverwrite table mis_month partition (dt) select nvl(sl.slid , ) as id,--水量 IDnvl(sl.hh …

【CORS 报错】跨域请求问题:CORS 多种环境下的解决方案

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、CORS错误的常见原因二、解决方案1. Vue3 Vite项目下的解决方案创建Vue3 Vite项目配置Vite的代理发送请求 2. jQuery项目下的解决方案使用CORS请求头使用JSONP 3. 其他环境下的解决方案使用服务器端代理设置CORS头使用…

使用django-haystack+whoosh实现全文搜索

前言 好像是上个星期在写代码的时候遇到了一些问题&#xff0c;这个问题似乎我之前也遇到过&#xff0c;印象中好像也写博客进行记录了的&#xff0c;于是就想在我的博客系统中“查找”&#xff08;表示很无奈居然没有搜索功能&#x1f979;&#x1f979;&#xff09;&#xff…

python--实验 9 类和对象

知识点 面向对象编程思想 面向对象编程是一种编程范式&#xff0c;它使用“对象”来设计软件&#xff0c;这些对象可以包含数据和代码&#xff0c;即属性和方法。 面向对象的程序设计的核心是对象,世间存在的万物皆为对象&#xff08;上帝式思维&#xff09; 面向对象&#xf…

科普文:一天学会shell编程

1.shell概叙 本文将从shell执行、语法、实战三个方面来讲解shell编程&#xff0c;其实shell编程就是个批处理&#xff0c;将你平时在服务器上单独执行的命令&#xff0c;按照一定要求组织起来&#xff0c;写在一起&#xff0c;然后统一执行&#xff0c;就完事了。 对于运维人员…

零基础小白人手必备“新华字典”,涵盖入门到进阶,超全语法!精炼总结64页,背完你的Python就牛了!

《Python背记手册》是一本旨在帮助初学者快速入门Python的实用手册&#xff0c;其特点鲜明&#xff0c;内容全面且易于理解。 书籍PDF已打包好&#xff0c;戳这里领取 一、书籍基本信息 作者&#xff1a;书籍的作者通常具有深厚的Python开发背景&#xff0c;有的作者是在美国攻…

MAVSDK示例takeoff_and_land编译与使用

1.克隆MAVSDK源码 ,示例位于源码的examples中 2.安装MAVSDK,下载https://github.com/mavlink/MAVSDK/releases/download/v2.12.2/mavsdk-windows-x64-release.zip 下载后解压:

三星首款智能戒指 Galaxy Ring 将于7月24日上市,售价399美元

三星电子即将推出其首款智能戒指——Galaxy Ring&#xff0c;这款创新的可穿戴设备将于7月24日上市&#xff0c;定价为399美元。Galaxy Ring的亮相标志着三星在智能穿戴设备领域的新突破&#xff0c;它不仅证明了三星在技术革新上的持续能力&#xff0c;也显示了其在健康和健身…

编号根据规则自增生成,及spring事务和锁

1、 背景 需要根据一些规则来生成自增编号&#xff0c;比如&#xff1a;95JS0001&#xff0c;950002 95JS是固定的&#xff0c;而后缀的0001的长度也是可配置的&#xff0c;因为有一张表来进行维护 CREATE TABLE number_control (id bigint NOT NULL AUTO_INCREMENT COMMENT 主…

DW03D是一款用于锂离子/聚合物电池保护的高集成度解决方案。DW03D包含内部功率MOSFET、高精度电压检测电路和延迟电路

一般概述 DW03D产品是单节锂离子/锂聚合物可充电电池组保护的高集成度解决方案。DW03D包括了先进的功率MOSFET&#xff0c;高精度的电压检测电路和延时电路。 DW03D具有非常小的TSS08-8的封装,这使得该器件非常适合应用于空间限制得非常小的可充电电池组应用。…

生信软件25 - 三代测序数据灵敏比对工具ngmlr

1. ngmlr简介 CoNvex Gap-cost Ments for Long Reads&#xff08;ngmlr&#xff09;是一种长reads比对工具&#xff0c;可以将PacBio或Oxford Nanopore灵敏地与&#xff08;大&#xff09;参考基因组&#xff08;比如人类参考基因组&#xff09;对齐&#xff0c;能快速和正确地…

OpenSSH Server远程代码执行漏洞 (CVE-2024-6387)|centos7升级到最新版本OpenSSH-9.8.p1

一、漏洞概述 漏洞名称 OpenSSH Server远程代码执行漏洞 CVE ID CVE-2024-6387 漏洞类型 竞争条件 发现时间 2024-07-01 漏洞评分 暂无 漏洞等级 高危 攻击向量 网络 所需权限 无 利用难度 高 用户交互 无 PoC/EXP 未公开 在野利用 未发现 OpenS…

MechMind结构光相机 采图SDK python调用

测试效果 Mech-Mind结构光相机 Mech Mind&#xff08;梅卡曼德&#xff09;的结构光相机&#xff0c;特别是Mech-Eye系列&#xff0c;是工业级的高精度3D相机&#xff0c;广泛应用于工业自动化、机器人导航、质量检测等多个领域。以下是对Mech Mind结构光相机的详细解析&#…

阿里巴巴国际站携手NBA传奇托尼·帕克,中国卖家又一波利好!

在全球化浪潮日益汹涌的今天&#xff0c;跨界合作已成为推动品牌国际化进程的重要力量。近日&#xff0c;阿里巴巴国际站宣布了一项震撼业界的合作——正式签约NBA&#xff08;美国职业篮球联赛&#xff09;传奇控球后卫托尼帕克&#xff08;Tony Parker&#xff09;作为其全球…