easy读取excel数据,包含合并数据
实例数据
1.监听器: @Slf4j public class CustomAnalysisEventListener<T> extends AnalysisEventListener<T> { private int headRowNum; public CustomAnalysisEventListener(int headRowNum) { this.headRowNum = headRowNum; } private List<T> list = new ArrayList<>(); private List<CellExtra> cellExtraList = new ArrayList<>(); @Override public void invoke(T excelData, AnalysisContext analysisContext) { // log.info(" data -> {}", excelData); list.add(excelData); } @Override public void extra(CellExtra extra, AnalysisContext context) { CellExtraTypeEnum type = extra.getType(); switch (type) { case MERGE: { if (extra.getRowIndex() >= headRowNum) { cellExtraList.add(extra); } break; } default:{ } } } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } public List<T> getList() { return list; } public List<CellExtra> getCellExtraList() { return cellExtraList; } } 2. @Slf4j public class ExcelListener extends AnalysisEventListener { /** * 可以通过实例获取该值 */ private List<Object> dataList = new ArrayList<>(); @Override public void invoke(Object object, AnalysisContext context) { //数据存储到list,供批量处理,或后续自己业务逻辑处理。 dataList.add(object); handleBusinessLogic(); /* //如数据过大,可以进行定量分批处理 if(dataList.size()>=200){ handleBusinessLogic(); dataList.clear(); } */ } @Override public void doAfterAllAnalysed(AnalysisContext context) { //非必要语句,查看导入的数据 log.info("导入的数据条数为: " + dataList.size()); } /** * 根据业务自行实现该方法,例如将解析好的dataList存储到数据库中 */ private void handleBusinessLogic() { // TODO } public List<Object> getDataList() { return dataList; } public void setDataList(List<Object> dataList) { this.dataList = dataList; } } 3. @Slf4j @Component public class ExcelRead { private static final int HEAD_ROW_NUM = 1; public static <T> List<T> list(MultipartFile file, Class<T> tClass) throws IOException { List<T> excelDataList; CustomAnalysisEventListener listener = new CustomAnalysisEventListener(HEAD_ROW_NUM); EasyExcel.read(file.getInputStream(), tClass, listener).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead(); excelDataList = listener.getList(); List<CellExtra> cellExtraList = listener.getCellExtraList(); if (cellExtraList != null && cellExtraList.size() > 0) { mergeExcelData(excelDataList, cellExtraList, HEAD_ROW_NUM); } return excelDataList; } private static <T> void mergeExcelData(List<T> excelDataList, List<CellExtra> cellExtraList, int headRowNum) { cellExtraList.forEach(cellExtra -> { int firstRowIndex = cellExtra.getFirstRowIndex() - headRowNum; int lastRowIndex = cellExtra.getLastRowIndex() - headRowNum; int firstColumnIndex = cellExtra.getFirstColumnIndex(); int lastColumnIndex = cellExtra.getLastColumnIndex(); //获取初始值 Object initValue = getInitValueFromList(firstRowIndex, firstColumnIndex, excelDataList); //设置值 for (int i = firstRowIndex; i <= lastRowIndex; i++) { for (int j = firstColumnIndex; j <= lastColumnIndex; j++) { setInitValueToList(initValue, i, j, excelDataList); } } }); } private static <T> void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, List<T> data) { Object object = data.get(rowIndex); for (Field field : object.getClass().getDeclaredFields()) { field.setAccessible(true); ExcelProperty annotation = field.getAnnotation(ExcelProperty.class); if (annotation != null) { if (annotation.index() == columnIndex) { try { field.set(object, filedValue); break; } catch (IllegalAccessException e) { log.error("设置合并单元格的值异常:{}", e.getMessage()); } } } } } private static <T> Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, List<T> data) { Object filedValue = null; Object object = data.get(firstRowIndex); for (Field field : object.getClass().getDeclaredFields()) { field.setAccessible(true); ExcelProperty annotation = field.getAnnotation(ExcelProperty.class); if (annotation != null) { if (annotation.index() == firstColumnIndex) { try { filedValue = field.get(object); break; } catch (IllegalAccessException e) { log.error("设置合并单元格的初始值异常:{}", e.getMessage()); } } } } return filedValue; } } 4.调用示例 list = ExcelRead.list(file, OilStationImportDTO.class);
5.实体类
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)