Excel多表头导入
EasyExcel官方文档
我导入的表格是多sheet页的,表头如下
下面是Excel导入接收数据的实体类
public class ExcelDataOneVo{
//下面三个属性分别对应上面Excel中的表头 大家根据自己的Excel模板编写自己的实体类
@ExcelProperty(value = {"标题","表头1","1"})
private String name;
@ExcelProperty(value = {"表头1","ABCDE"})
private String name;
@ExcelProperty(value = {"表头1"})
private String name;
}
下面是导入处理方法
serviceImpl
@Override
public AjaxResult importEmpBasicInfo(MultipartFile file) {
try {
List<String> resultError=new ArrayList<>();
//获取操作人员的姓名
String username = SecurityUtils.getUsername();
//我这里是加载了单位部门的信息,主要是用来根据单位名称匹配单位id的
loadDeptInfoAndPostInfo();
ExcelReader excelReader = EasyExcel.read(file.getInputStream()).build();
//这是两个监听器,用来把导入的Excel解析为我们所需要的数据
ExcelEmpBasicListener excelEmpBasicListener=new ExcelEmpBasicListener();
ExcelEmpDegreeListener excelEmpDegreeListener=new ExcelEmpDegreeListener();
//这里的sheetName1 2 是sheet页的名称 也可以根据sheet页的下标来写,我这里采用了直接读取sheet页名称
ReadSheet sheet1 = EasyExcel.readSheet("sheetName1").head(StaffBasicInfoExcel.class).registerReadListener(excelEmpBasicListener).build();
ReadSheet sheet2 = EasyExcel.readSheet("sheetName2").head(StaffDegreeInfoExcel.class).registerReadListener(excelEmpDegreeListener).build();
//这里需要注意,.headRowNumber(3) 如果这个不指定表头是几行,那么多表头行的sheet读取上来就会一直是null
ReadSheet sheet3 = EasyExcel.readSheet("sheetName3").head(StaffRewardInfoExcel.class).headRowNumber(3).registerReadListener(excelEmpRewardListener).build();
excelReader.read(sheet1);
excelReader.read(sheet2);
excelReader.finish();
//基础信息
List<StaffBasicInfoExcel> basicInfo = excelEmpBasicListener.getDataList();
// 学历信息
List<StaffDegreeInfoExcel> degreeInfo = excelEmpDegreeListener.getDataList();
if (ObjectUtils.isNotEmpty(basicInfo)) {
List<String> strings = updateEmpBasicInfo(basicInfo, username);
resultError.addAll(strings);
}
if (ObjectUtils.isNotEmpty(degreeInfo)){
List<String> strings = updateEmpDegreeInfo(degreeInfo, username);
resultError.addAll(strings);
}
if (ObjectUtils.isNotEmpty(resultError)){
return AjaxResult.error("导入失败信息数据",resultError);
}else {
return AjaxResult.success();
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
//这里是清楚监听器中list的数据 必须清楚,不然再次导入的时候数据会一直累积上去
ExcelEmpBasicListener.clearDataList();
ExcelEmpDegreeListener.clearDataList();
}
这是监听器的代码
这里面基本上没啥需要改的 只需要换对应的实体类就行,如果遇其他表头的处理什么的,根据官方文档进行操作
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.fastjson2.JSON;
import com.bms.project.govern.excel.StaffInfoExcel.StaffBasicInfoExcel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @className: ExcelEmpBasicListener
* @author: qh
* @date: 2024/9/2 15:50
* @Version: 1.0
* @description:
*/
public class ExcelEmpBasicListener extends AnalysisEventListener<StaffBasicInfoExcel> {
private static final Logger log = LoggerFactory.getLogger(ExcelEmpBasicListener.class);
/**
* 行索引(多行表头)
*/
private static Integer rowIndex = 0;
/**
* 导入的障碍物数据
*/
private static List<StaffBasicInfoExcel> list = new ArrayList<StaffBasicInfoExcel>();
/**
* 每读一行内容都会调用invoke,在invoke中可以操作读取到的数据
* @param staffBasicInfoExcel 解析的数据
* @param analysisContext 解析的上下文对象
*/
@Override
public void invoke(StaffBasicInfoExcel staffBasicInfoExcel, AnalysisContext analysisContext) {
log.info("解析数据:" + JSON.toJSONString(staffBasicInfoExcel));
list.add(staffBasicInfoExcel);
}
@Override
public void extra(CellExtra extra, AnalysisContext context) {
super.extra(extra, context);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
@Override
public boolean hasNext(AnalysisContext context) {
return super.hasNext(context);
}
/**
* 这里会一行行的返回头
* 监听器只需要重写这个方法就可以读取到头信息
* @param headMap
* @param context
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// 读到下个sheet页的表头则重新计数,只读取障碍物的基础数据
rowIndex = 0;
log.info("解析到一条头数据:" + JSON.toJSONString(headMap));
}
/**
* 监听器实现这个方法就可以在读取数据的时候获取到异常信息
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
}
/**
* 获取数据
*/
public List<StaffBasicInfoExcel> getDataList(){
return list;
}
/**
* 清除数据
*/
public static void clearDataList(){
list.clear();
}
}