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

使用EasyExcel实现excel导入

下文将简述在SpringBoot如何使用EasyExcel,从多sheet页,上万级数据excel导入到数据库中,本文使用mybatis作为ORM映射框架
在这里插入图片描述

准备环境

创建用户表users
在这里插入图片描述
创建用户实体对象级底层方法
在这里插入图片描述
userMapper.xml中定义批量增加方法

  <insert id="batchSave" parameterType="java.util.List">
        insert into users(user_name,password,age,email,auth)
        values
        <foreach collection="userVoList" item="item" index="id" separator=",">
           (#{item.userName},#{item.password},#{item.age},#{item.email},#{item.auth})
        </foreach>
    </insert>

其他业务方法不在赘述,下面开始使用EasyExcel
官方文档

1.引入依赖

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

2.准备一个待导入的excel

在这里插入图片描述

2.定义一个excel列名和实体的映射类

ExcelProperty 用于指定列名,此处也可以使用index指定列;
还可以使用 @NumberFormat进行数字格式化如:
保留两位小数@NumberFormat(“#.##%”)
使用 @DateTimeFormat进行日期格式化如:
@DateTimeFormat(“yyyy-MM-dd”)

@Data
public class ConverterData {
    private Integer id;
    @ExcelProperty("名称")
    private String userName;
    @ExcelProperty("密码")
    private String password;
    /**
     * 年龄
     */
    @ExcelProperty("年龄")
    private Integer age;
    /**
     * email
     */
    @ExcelProperty("邮箱地址")
    private String email;
    /**
     * 权限
     */
    @ExcelProperty("权限")
    private String auth;
}

2.定义一个监听器ReadListener

@Slf4j
public class UserListener implements ReadListener<ConverterData> {
    private static final int BATCH_COUNT=100;//定义批量处理的条数
    private List<UserVo> cacheDataList= ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);//用于缓存解析的数据
    UserService userService;
    public UserListener(){
        userService=new UserServiceImpl();
    }
    public UserListener(UserService userService){
        this.userService=userService;
    }
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {

        ReadListener.super.onException(exception, context);
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        ReadListener.super.invokeHead(headMap, context);
    }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        ReadListener.super.extra(extra, context);
    }

    @Override
    public boolean hasNext(AnalysisContext context) {
        return ReadListener.super.hasNext(context);
    }

    /**
     * 每一条数据都会调用,当集合的大小等于定义的批量处理大小就会保存到数据库
     * @param converterData excel映射对象
     * @param analysisContext
     */
    @Override
    public void invoke(ConverterData converterData, AnalysisContext analysisContext) {
        log.info("解析到数据:"+new Gson().toJson(converterData));
        String userName= converterData.getUserName();
        String password=converterData.getPassword();
        if(StringUtil.isNullOrEmpty(userName)||StringUtil.isNullOrEmpty(password)){
            return;
        }
        //转换成实体类
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(converterData,userVo);
        cacheDataList.add(userVo);
        if(cacheDataList.size()>=BATCH_COUNT){//
            saveData();
            cacheDataList=ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成了 都会来调用,遗留的数据
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
    }

    /**
     * 保存数据
     */
    private void saveData(){
        log.info(cacheDataList.size()+"条数据开始存储数据库");
        userService.batchSave(cacheDataList);
        log.info("保存成功");

    }
}

3.导入单个sheet页的excel,直接在Test中测试.数据行804
在这里插入图片描述

在这里插入图片描述

  String filePath="D:\\workspace"+ File.separator+"1.xlsx";
  long pre= System.currentTimeMillis();
  EasyExcel.read(filePath, ConverterData.class,new UserListener(userService)).sheet().doRead();
 long now = System.currentTimeMillis();
  System.out.println("导入耗时"+(now-pre)+"ms");

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f9407166088f494f973f5cb16b5ac79a.png

测试结果804行数据,花费844ms

4.导入多个sheet页数据,先获取sheet页在执行导入操作

导入前数据条数:
在这里插入图片描述

    ExcelReader excelReader = EasyExcel.read(filePath).build();
        ExcelReadExecutor excelReadExecutor = excelReader.excelExecutor();
        List<ReadSheet> readSheets = excelReadExecutor.sheetList();
        UserListener userListener = new UserListener(userService);
        for(ReadSheet sheet:readSheets){
            ReadSheet sheet1 = EasyExcel.readSheet(sheet.getSheetNo()).head(ConverterData.class).registerReadListener(userListener).build();
            excelReader.read(sheet1);
        }

在这里插入图片描述
10个sheet,1w+数据
在这里插入图片描述
在这里插入图片描述
以上内容来自easyExcel官网,更多内容请查看官网


http://www.kler.cn/a/387012.html

相关文章:

  • SpringBoot实战(三十一)集成iText5,实现RSA签署PDF
  • 1.两数之和-力扣(LeetCode)
  • 【计算机网络】TCP网络程序
  • git配置远程仓库的认证信息
  • elementui el-table中给表头 el-table-column 加一个鼠标移入提示说明
  • Elasticsearch 实战应用:高效搜索与数据分析
  • 31.7K+ Star!AgentGPT:一个在浏览器中运行的Agent
  • 全排列(DFS)
  • 【MIT-OS6.S081笔记1】Chapter1阅读摘要:Operating system interfaces
  • Spring Boot的过滤器与拦截器的区别
  • 【C++ 滑动窗口】2134. 最少交换次数来组合所有的 1 II
  • Anaconda安装和环境配置教程(2024年11月9日)
  • Kafka 之事务消息
  • GJ Round (2024.10) Round 8~21
  • 鸿蒙多线程开发——Worker多线程
  • 安全见闻(网络安全篇)
  • Python爬虫如何处理验证码与登录
  • Python练习15
  • Qt 无法获取调试输出
  • SpringBoot助力的共享汽车业务优化系统
  • 【c++丨STL】vector模拟实现
  • JAVA 多线程之ForkJoin
  • 发现了NitroShare的一个bug
  • 关于vue如何监听route和state以及各自对应的实际场景
  • 103 - Lecture 1
  • Web前端开发--HTML语言