这篇文章距离最后更新已过394 天,如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!
- 监听器(用MyBatis的IService接口做了封装)
package io.github.talelin.latticy.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.IService;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Map;
@Slf4j
public class ExcelReaderListener<T> extends AnalysisEventListener<T> {
/**
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/
private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
/**
* 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
*/
private IService<T> service;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*
* @param service
*/
public ExcelReaderListener(IService<T> service) {
this.service = service;
}
/**
* 这个每一条数据解析都会来调用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(T data, AnalysisContext context) {
log.info("解析到一条数据:{}", JSON.toJSONString(data));
cachedDataList.add(data);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
//注意ListUtils.newArrayListWithExpectedSize是在EasyExcel3.1.1版本之后才有的
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
log.info("表头数据 excelHead= {}", headMap);
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
log.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", cachedDataList.size());
service.saveBatch(cachedDataList);
log.info("存储数据库成功!");
}
}
@PostMapping("/import")
public AjaxResult importExcel(MultipartFile file) throws IOException {
AjaxResult ajaxResult = new AjaxResult();
try {
//file.getInputStream()是获取导入的文件数据
//SStbkSmbsnFncDtlI01ADO.class是对应的实体类
//YwtzTyrzmxCwbListener是对应的监听器,这里是自定义对导入的数据做判断限制
//sStbkSmbsnFncDtlI01AService是对应的Service类
//.sheet()第一个参数是Excel哪个中sheet,第二个参数是sheet名称
//.headRowNumber()是表头行数
//.doRead()开始读取
EasyExcel.read(file.getInputStream(), SStbkSmbsnFncDtlI01ADO.class, new YwtzTyrzmxCwbListener(sStbkSmbsnFncDtlI01AService)).sheet(1, "02表内容").headRowNumber(3).doRead();
return ajaxResult.success("success");
} catch (ExcelAnalysisException e) {
e.printStackTrace();
return ajaxResult.fail("500", e.getMessage());
}
}
package io.github.talelin.latticy.model;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* B_H01_同业融资信息_财务部_补录
*
* @author generator@TaleLin
* @since 2022-09-05
*/
@Data
public class SStbkSmbsnFncInfH01ADO implements Serializable {
/**
* 客户号
*/
//强制读取第一个
//这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
//用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
@ExcelProperty(index = 0)
private String cstNo;
/**
* 业务编码
*/
@ExcelProperty(index = 1)
private String bsnEcd;
/**
* 业务种类
*/
@ExcelProperty(index = 2)
private String bsnCtlg;
/**
* 起始日期
*/
@ExcelProperty(index = 3)
private String begDt;
/**
* 到期日
*/
@ExcelProperty(index = 4)
private String exdy;
/**
* 实际终止日期
*/
@ExcelProperty(index = 5)
private String actTmdt;
/**
* 期限
*/
@ExcelProperty(index = 6)
private String ddln;
/**
* 利率类型
*/
@ExcelProperty(index = 7)
private String intrtTp;
/**
* 实际利率
*/
@ExcelProperty(index = 8)
private BigDecimal actIntrt;
/**
* 借贷定价基准类型
*/
@ExcelProperty(index = 9)
private String dbtcrPrcgBssTp;
/**
* 基准利率
*/
@ExcelProperty(index = 10)
private BigDecimal bssIntrt;
/**
* 计息方式
*/
@ExcelProperty(index = 11)
private String intarMod;
/**
* 利率浮动频率
*/
@ExcelProperty(index = 12)
private String intrtFltFrq;
/**
* 余额
*/
@ExcelProperty(index = 13)
private BigDecimal bal;
/**
* 内部机构号
*/
@ExcelProperty(index = 14)
private String inrInsno;
/**
* 币种
*/
@ExcelProperty(index = 15)
private String ccy;
/**
* 数据来源
*/
@ExcelIgnore
private String dtsrc;
/**
* 业务日期
*/
//忽略这个字段
@ExcelIgnore
private String parDate;
/**
* 源系统代码
*/
@ExcelIgnore
private String srcSysCd;
/**
* 加载时间戳
*/
@ExcelIgnore
private String loadTime;
/**
* 金融机构代码
*/
@ExcelProperty(index = 16)
private String fncLcnsNo;
/**
* 交易对手代码
*/
@ExcelProperty(index = 17)
private String txnOpntCd;
/**
* 交易对手证件类别
*/
@ExcelProperty(index = 18)
private String txnOpntCrdtCgy;
/**
* 资产负债类型
*/
@ExcelProperty(index = 19)
private String alTp;
/**
* 余额折人民币
*/
@ExcelProperty(index = 20)
private BigDecimal balFoldCny;
/**
* 存款协议代码
*/
@ExcelProperty(index = 21)
private String depAgrmCd;
/**
* 缴存准备金方式
*/
@ExcelProperty(index = 22)
private String depRsrvfndMtd;
/**
* 合同编码
*/
@ExcelProperty(index = 23)
private String ctrEcd;
}