依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
监听器:
package com.hawkcloud.excel.tool;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author R
* @Description //TODO easyExcel导入 listen 监听器
* @Date 2021/9/23 10:56 上午
**/
@Slf4j
public class EasyExcelDataListener extends AnalysisEventListener<Map<Integer, Object>> {
// TODO Map<Integer, Object> 表示监听excel的每条信息
@Resource
private IExcelService excelService = SpringUtil.getBean(IExcelService.class);
/**
* 每隔10000条存储数据库,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100000;
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Map<Integer, String> map = new HashMap<>();
private ExcelParam excelParam;
/**
* 表头
*
* @param headMap
* @param context
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
log.error("表头信息:" + headMap);
map.putAll(headMap);
}
@Override
public void invoke(Map<Integer, Object> data, AnalysisContext analysisContext) {
Map<String, Object> objectMap = new HashMap<>();
log.info("解析到一条数据: " + JSON.toJSONString(data));
// TODO 根据具体的使用,转变为保存形式的map(表头为key,表体数据为value)
data.forEach((key, value) -> {
Object mapKey = map.get(key);
if (Func.isNotEmpty(mapKey)) {
objectMap.put((String) mapKey, value);
}
});
list.add(objectMap);
if (list.size() >= BATCH_COUNT) {
log.error("解析100000条数据结束!");
saveData();
list.clear();
}
}
/**
* 所有数据解析完成了 调用此方法
*
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
log.error("所有数据解析完成!");
}
/**
* 参数-ExcelParam对象(在Listener中使用其他类的参数,需要定义全局变量,在使用监听器时,将变量写入)
*
* @param excelParam
*/
public void parameter(ExcelParam excelParam) {
this.excelParam = excelParam;
}
/**
* 存储数据库
*/
private void saveData() {
log.error(list.size() + " 条数据,开始存储数据库!");
long start = System.currentTimeMillis();
// TODO 业务逻辑----保存数据库
excelService.saveExcel(excelParam, AuthUtil.getTenantId(), list);
long end = System.currentTimeMillis();
log.error("存储数据库成功!耗时:" + (end - start) / 1000L + "秒");
}
}
使用:
public void readExcel(MultipartFile multipartFile,ExcelParam excelParam){
// 获取文件名
String fileName=multipartFile.getOriginalFilename();
// 获取文件后缀名
assert fileName!=null;
String suffix=fileName.substring(fileName.lastIndexOf("."));
if(XLS_SUFFIX.equals(suffix)||XLSX_SUFFIX.equals(suffix)){
// .xlsx文件 .xls文件
try{
//定义监听器,将自定义参数写入全局
EasyExcelDataListener easyExcelDataListener=new EasyExcelDataListener();
easyExcelDataListener.parameter(excelParam);
//使用监听器写入excel
EasyExcel.read(multipartFile.getInputStream(),easyExcelDataListener).sheet().headRowNumber(1).doReadSync();
}catch(IOException e){
throw new RuntimeException("Excel数据读取异常:"+e.getMessage(),e);
}
}else{
// 不支持格式,抛出异常
throw new RuntimeException("不支持的Excel文件格式!");
}
}