Easyexcel分批读取excel数据,海量excel数据量的读取存入数据库的实际操作
easyexcel
快速、简洁、解决大文件内存溢出的java处理Excel工具
项目地址:https://gitcode.com/gh_mirrors/ea/easyexcel
免费下载资源
·
对于海量excel的数据读取,如获取对账文件,第三方订单信息等等,为了避免内存溢出,我们通常会进行分批读取入库的操作,这里我们使用阿里巴巴开源的 easyexcel 工具类进行操作,为了减少踩坑,我们先看官网,官网写的很清晰, 个人也是按照官网的代码示例来进行操作,这里只使用监听方式读取
这里使用监听器的方式,根据设置每批次数据量的大小,当list里面数据量达到设置每批次最大数据量时,进行入库操作,海量数据的话,通常每批次1000的速度最快,贴一下代码,下面做一下解释,首先引入maven组件
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
监听方式 读取代码,参数看个人需要进行配置
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.qx.boot.trm.controller.AgtPftDayStlController;
import com.qx.boot.trm.dto.CheckTransInfoDto;
import com.qx.boot.trm.mapper.CheckTransInfoMapper;
import com.qx.boot.util.utils.TdDateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @version V1.0
* @author: hqk
* @date: 2020/12/30 10:52
* @Description: 对账excel读取, 用于大数据量 excel 导入监听器, 用于循环处理excel 保存数据
* 此类不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
*/
public class ExcelModelListener extends AnalysisEventListener<CheckTransInfoDto> {
private Logger logger = LoggerFactory.getLogger(ExcelModelListener.class);
/**
* 每隔 1000条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 1000;
// 存款的list对象
List<CheckTransInfoDto> list = new ArrayList<CheckTransInfoDto>();
// 存储数据的 dao层
private CheckTransInfoMapper checkTransInfoMapper;
// 自定义参数 不需要可以去掉 需要多少可以自己加
private String checkDt;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*
* @param checkTransInfoMapper
*/
public ExcelModelListener(CheckTransInfoMapper checkTransInfoMapper,String checkDt) {
this.checkTransInfoMapper = checkTransInfoMapper;
this.checkDt = checkDt;
}
public ExcelModelListener() {
}
/**
* 这个每一条数据解析都会来调用
*
* @param checkTransInfoDto
* one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param analysisContext
*/
@Override
public void invoke(CheckTransInfoDto checkTransInfoDto, AnalysisContext analysisContext) {
list.add(checkTransInfoDto);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
list.clear();
}
}
/**
* 所有数据解析完成了 都会来调用
*
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
logger.info("所有数据解析完成!");
}
/**
* 存储数据
*/
private void saveData() {
logger.info("{}条数据,开始存储数据库!", list.size());
//checkTransInfoMapper.saveCheckTransInfo(list, checkDt);
for (int i = 0; i < list.size() ; i++) {
System.out.println(JSON.toJSONString(list.get(i)));
}
logger.info("存储数据库成功!");
}
}
实体对象里面,这里用注解方式,和excel表头字段一一对应
/**
* @version V1.0
* @author: hqk
* @date: 2020/12/30 19:49
* @Description: 读取对账 excel 实体
*/
public class CheckTransInfoDto {
/** 交易订单号 */
@ExcelProperty(value = "交易订单号")
private String transOrderNo;
/** 交易商户编号 */
@ExcelProperty(value = "交易商户编号")
private String transMercId;
/** 结算商户编号 */
@ExcelProperty(value = "结算商户编号")
private String smtMercId;
/** 交易银行卡号 */
@ExcelProperty(value = "银行卡号")
private String crdNo;
// get set 方法
}
接下来看一下如何调用
@RestController
public class TestController {
@Autowired
private CheckTransInfoMapper checkTransInfoMapper;
@RequestMapping("testExcel")
public void test(){
EasyExcel.read(filePath, CheckTransInfoDto.class,
new ExcelModelListener(checkTransInfoMapper,"20210115")).sheet().doRead();
}
}
’官网写的也很详细,按照官网来就可以的,这样就可以实现分批读取Excel的数据了,
GitHub 加速计划 / ea / easyexcel
31.64 K
7.47 K
下载
快速、简洁、解决大文件内存溢出的java处理Excel工具
最近提交(Master分支:3 个月前 )
c42183df
Bugfix 3 个月前
efa7dff6 * 重新加回 `commons-io`
3 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)