alibaba-easyExcel动态列导入导出
一、导入Maven依赖dependency groupIdcom.alibaba/groupId artifactIdeasyexcel/artifactId version4.0.2/version typepom/type scopeimport/scope /dependency二、service层//当前年指标项--动态列头 MapString, EntInput entInputMap list.stream().collect(Collectors.toMap(EntInput::getItemCode, Function.identity())); //过滤必传列头 ListString required Optional.ofNullable(list).get().stream().filter(entInputCompare - { return entInputCompare.getStatus() -1; }).map(EntInput::getItemName).collect(Collectors.toList()); //监听拦截校验 EasyExcelListener readListener new EasyExcelListener(required, list); EasyExcel.read(multipartFile.getInputStream(), readListener).sheet().headRowNumber(indexStart - 1).doRead(); MapString, Integer nameIndexHeaderMap readListener.getNameIndexHeaderMap(); for (String string : required) { if (!nameIndexHeaderMap.containsKey(string)) { throw new ServerException(导入失败,请按照模版导入); } }三、监听层package org.captain.modules.excel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.CellExtra; import lombok.Getter; import org.captain.core.log.exception.ServiceException; import org.captain.core.tool.utils.DateTimeUtil; import org.captain.core.tool.utils.StringUtil; import org.captain.modules.ent.entity.EntInput; import org.captain.modules.enums.StatusEntInput; import java.math.BigDecimal; import java.util.*; public class EasyExcelListener extends AnalysisEventListenerMapInteger, String { //表头数据存储所有的表头数据 private ListMapInteger, String headList new ArrayList(); private ListString headNameList new ArrayList(); private MapInteger, String indexNameHeaderMap new HashMap(); Getter private MapString, Integer nameIndexHeaderMap new HashMap(); //数据体 private ListMapInteger, String dataList new ArrayList(); private ListInteger requiredIndex new ArrayList(); private ListString required; private ListEntInput headerCheck; Getter private MapInteger, EntInput headerCheckMap new HashMap(); Getter private MapString, EntInput entInputLogMap new HashMap(); Getter private MapString, Integer entTypeMap new LinkedHashMapString, Integer(); private StringBuffer checkMessage new StringBuffer(); private Integer firstDataRow 0; private Integer startHeaderRow 1; //默认开始行从0开始 public EasyExcelListener(ListString required, ListEntInput headerCheck) { this.required required; this.headerCheck headerCheck; } Override//这里会一行行的返回头 public void invokeHeadMap(MapInteger, String headMap, AnalysisContext context) { //存储全部表头数据 Integer currentRowNum context.getCurrentRowNum(); if (currentRowNum startHeaderRow) { return; } for (Integer keyNext : headMap.keySet()) { String valuesNext headMap.get(keyNext); if (valuesNext ! null) { String replace valuesNext.replace((char) 12288, ); valuesNext replace.trim(); } if (currentRowNum startHeaderRow) { //代表是树形的第一行 当树形列名为空时赋值前一列名的值 String firstTree Optional.ofNullable(valuesNext).orElse(headMap.get(keyNext - 1)).trim(); headMap.put(keyNext, firstTree); headNameList.add(firstTree); nameIndexHeaderMap.put(firstTree, keyNext); if (required.contains(firstTree)) { requiredIndex.add(keyNext); } indexNameHeaderMap.put(keyNext, firstTree); } else { //树行的第二层 String last headList.get(headList.size() - 1).get(keyNext); String current Optional.ofNullable(valuesNext).orElse().trim(); if (last!null!last.equals(current)) { String values last current; headMap.put(keyNext, values); headNameList.add(values); indexNameHeaderMap.put(keyNext, values); nameIndexHeaderMap.put(values, keyNext); } } } headList.add(headMap); } Override// 处理每一行数据 ,列号从0 开始计数 public void invoke(MapInteger, String data, AnalysisContext context) { if (firstDataRow 0) { for (EntInput input : headerCheck) { if (Objects.equals(input.getStatus(), StatusEntInput.EntInfo.getStatus())) { if (!headNameList.contains(input.getItemName())) { throw new ServiceException(列头缺失input.getItemName()请按下载模版导入); } } if (input.getStatus() 1) { //为一对多的企业类型项 entTypeMap.put(input.getItemName(), nameIndexHeaderMap.get(input.getItemName().trim())); //因为导入是多列但是实际为一个属性值概念只记录一次企业类型项 if (input.getFlag()) { entInputLogMap.put(企业类型数据项, input); } } if (input.getStatus() 0 input.getFlag()) { entInputLogMap.put(input.getItemName(), input); } headerCheckMap.put(nameIndexHeaderMap.get(input.getItemName()), input); } firstDataRow; } dataList.add(data); boolean flag; for (Map.EntryInteger, String entry : data.entrySet()) { Integer integer entry.getKey(); String s entry.getValue(); flag false; StringBuilder message new StringBuilder(); message.append(第).append(dataList.size()).append(行数据找不到必传数据列头名为); if (requiredIndex.contains(integer) StringUtil.isBlank(s)) { flag true; message.append(indexNameHeaderMap.get(integer),); } if (flag) { checkMessage.append(message).append(\n); } } } Override// 全部处理结束执行 public void doAfterAllAnalysed(AnalysisContext context) { if (StringUtil.isNotBlank(checkMessage.toString())) { throw new ServiceException(checkMessage.toString()); } } Override public void extra(CellExtra extra, AnalysisContext context) { } public ListMapInteger, String getDataList() { return dataList; } }主要通过利用map结构对表头进行确定和数据整理对齐这个方式适合各种业务场景。前提是一个sheet只有一个表头的情况如果多个则需要自写excel导入相关