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

EasyExcel如何读取全部Sheet页数据方法

一、需求描述

Excel表格里面大约有20个sheet页,每个sheet页65535条数据,需要读取全部数据,并导入至数据库。

找了好多种方式,EasyExcel比较符合,下面看代码。

二、实现方式 采用EasyExcel框架的doReadAll()方法

 1、DemoController

    /**
     * 导入文件分析
     */
    public void importAll()
    {
    	 String fileName = "D:\\aa.xlsx";
    	//读取所有Sheet的数据.每次读完一个Sheet就会调用这个方法
    	EasyExcel.read(fileName, new EasyExceGeneralDatalListener(empService)).doReadAll();
    }

 2、EmpService 

import java.util.List;
import java.util.Map;

public interface EmpService 
{
    public void importData(List<Map<Integer, String>> dataList);
}

 3、EmpServiceImpl 

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.ruoyi.imp.service.EmpService;
import com.ruoyi.jdbc.util.JDBCDruidUtils;

@Service
public class EmpServiceImpl implements EmpService 
{

	/*
     * 测试用Excel导入超过10w条数据,经过测试发现,使用Mybatis的批量插入速度非常慢,所以这里可以使用 数据分批+JDBC分批插入+事务来继续插入速度会非常快
    */
    @Override
    public void importData(List<Map<Integer, String>> dataList) {
        //结果集中数据为0时,结束方法.进行下一次调用
        if (dataList.size() == 0) {
            return;
        }
        //JDBC分批插入+事务操作完成对20w数据的插入
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            long startTime = System.currentTimeMillis();
            System.out.println("此次共"+dataList.size() + "条数据,导入开始时间:" + startTime + "ms");
            // JDBCDruidUtils.getConnection() 此部分为JDBC连接,百度一下就有
            conn = JDBCDruidUtils.getConnection();
            //控制事务:默认不提交
            conn.setAutoCommit(false);
            String sql = "insert into tp_import_all (wy,kh,ch,dk,on,wlc,ncv,mc,jmc) values";
            sql += "(?,?,?,?,?,?,?,?,?)";
            ps = conn.prepareStatement(sql);
            //循环结果集:这里循环不支持"烂布袋"表达式
            for (int i = 0; i < dataList.size(); i++) {
                Map<Integer, String> item = dataList.get(i);
                ps.setString(1, item.get(0));
                ps.setString(2, item.get(1));
                ps.setString(3, item.get(2));
                ps.setString(4, item.get(3));
                ps.setString(5, item.get(4));
                ps.setString(6, item.get(5));
                ps.setString(7, item.get(6));
                ps.setString(8, item.get(7));
                ps.setString(9, item.get(8));
                //将一组参数添加到此 PreparedStatement 对象的批处理命令中。
                ps.addBatch();
            }
            System.out.println("importData方法,executeBatch()...开始执行");
            //执行批处理
            ps.executeBatch();
            System.out.println("importData方法,executeBatch()...执行结束");
            System.out.println("importData方法,commit()...开始提交");
            //手动提交事务
            conn.commit();
            System.out.println("importData方法,commit()...提交结束");
            long endTime = System.currentTimeMillis();
            System.out.println(dataList.size() + "条,导入结束时间:" + endTime + "ms");
            System.out.println("导入用时:" + (endTime - startTime) + "ms");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("catch Exception e");
        } finally {
            //关连接
            JDBCDruidUtils.close(conn, ps);
            System.out.println("JDBCDruidUtils.close 关连接");
        }
    }

}

4、EasyExceGeneralDatalListener 

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.imp.service.EmpService;

// 事件监听
public class EasyExceGeneralDatalListener extends AnalysisEventListener<Map<Integer, String>> {
    /**
     * 处理业务逻辑的Service,也可以是Mapper
     */
    private EmpService  empService;

    /**
     * 用于存储读取的数据
     */
    private List<Map<Integer, String>> dataList = new ArrayList<Map<Integer, String>>();

    public EasyExceGeneralDatalListener() {
    }
    
    public EasyExceGeneralDatalListener(EmpService empService) {
        this.empService = empService;
    }

	@Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        //数据add进入集合
        dataList.add(data);
        //size是否为100000条:这里其实就是分批.当数据等于20w的时候执行一次插入
        if (dataList.size() >= ExcelConstants.GENERAL_ONCE_SAVE_TO_DB_ROWS) {//ExcelConstants.GENERAL_ONCE_SAVE_TO_DB_ROWS Integer类型,控制条数
            //存入数据库:数据小于1w条使用Mybatis的批量插入即可;
            saveData();
            //清理集合便于GC回收
            dataList.clear();
        }
    }

    /**
     * 保存数据到DB
     *
     * @param
     * @MethodName: saveData
     * @return: void
     */
    private void saveData() {
    	System.out.println("saveData方法,importData...开始");
        //    
    	empService.importData(dataList);
    	System.out.println("saveData方法,importData...结束");
        // 回收
        dataList.clear();
    }
    
    /**
     * Excel中所有数据解析完毕会调用此方法
     *
     * @param: context
     * @MethodName: doAfterAllAnalysed
     * @return: void
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
    	System.out.println("doAfterAllAnalysed方法,saveData...开始");
        // 调用方法
        saveData();
        System.out.println("doAfterAllAnalysed方法,saveData...结束");
        // 回收
        dataList.clear();
    }
}

三、其他问题

 1、所用版本

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

2、可能会碰到null的报错,可以检查下poi版本是否冲突,这边用的4.1的版本

如果出现poi-ooxml是4.x版本,poi是3.x  可能会出错


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

相关文章:

  • 人工智能的前沿研究方向与未来发展趋势
  • C语言第十一周课——函数的调用
  • Oracle OCP认证考试考点详解082系列16
  • Java API类与接口:类的转换方法与正则表达式
  • LeetCode【0018】四数之和
  • Python酷库之旅-第三方库Pandas(206)
  • leetcode刷题:611.有效三角形的个数(双指针实现)
  • C++中单引号‘‘和双引号““的区别
  • Linux内核上游提交完整流程及示例
  • 多人聊天室
  • Python实现广义线性回归模型(statsmodels GLM算法)项目实战
  • Oracle 查询语句限制只选择最前面几行,和最后面几行的实现方式。
  • GAN:WGAN前作
  • 【玩转TableAgent 数据智能分析】-- 数据分析不再是专业人士的专利
  • 如何使用Net2FTP轻松部署本地Web文件管理器并远程访问管理内网资源?
  • [⑦ADRV902x]: JESD204学习笔记
  • 【Spark基础】-- 宽窄依赖
  • 【学习笔记】插值之拉格朗日插值(Lagrange)
  • springboot中@Builder注解的详细用法实例,跟数据库结合。
  • Leetcode226. 翻转二叉树
  • Python语言基础知识(一)
  • 第三方实验室LIMS管理系统源码,asp.net LIMS源码
  • java实现Modbus通信
  • 文心一言大模型应用开发入门
  • 外汇市场中的多头和空头究竟是什么?如何通过K线图来辨别它们呢?
  • 快速排序并不难