EasyExcel解析包含单元格合并的表格

EasyExcel解析包含单元格合并的表格

1,引入依赖

com.alibaba easyexcel 2.2.7

2,实现代码
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.CellExtra;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileNotFoundException;
import java.util.*;

/**

  • @Description 注意:空白的单元格不会被读取

  • @Author dsf

  • @Date 2020/12/14 15:30

  • @Version V1.0
    **/
    public class NoModelDataListener extends AnalysisEventListener<Map<Integer, String>> {

    private static final Logger log = LoggerFactory.getLogger(UploadDataListener.class);
    /**

    • 所有列到字段名的映射
    • /
      private Map<Integer,String> index2FieldMap ;
      /
      *
    • 解析出的数据
      /
      private LinkedHashMap<Integer,Map<Integer, String>> row2DataMap = new LinkedHashMap<>();
      /
      *
    • 合并单元格
      */
      private List extraMergeInfoList = new ArrayList<>();

    public NoModelDataListener(){}

    public NoModelDataListener(Map<Integer,String> index2FieldMap){
    this.index2FieldMap = index2FieldMap ;
    }

    @Override
    public void invoke(Map<Integer, String> rowData, AnalysisContext analysisContext) {
    //读取到的每行数据,其key是以0开始的索引
    row2DataMap.put(analysisContext.readRowHolder().getRowIndex(),rowData) ;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    //所有行都解析完成
    this.explainMergeData(row2DataMap, extraMergeInfoList) ;
    }

    /**

    • 某行的数据解析失败
    • */
      @Override
      public void onException(Exception exception, AnalysisContext context) {
      System.err.println("解析失败,但是继续解析下一行: " + exception.getMessage());
      // 如果是某一个单元格的转换异常 能获取到具体行号
      if (exception instanceof ExcelDataConvertException) {
      ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;
      System.err.println(“第{}行,第{}列解析异常” + excelDataConvertException.getRowIndex() +
      excelDataConvertException.getColumnIndex());
      }
      }

    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
    switch (extra.getType()){
    case MERGE:{
    extraMergeInfoList.add(extra);
    break;
    }
    case HYPERLINK:{
    break;
    }
    case COMMENT:{
    }
    default: {
    }
    }
    }

    /**

    • 处理合并单元格

    • @param data 解析数据

    • @param extraMergeInfoList 合并单元格信息

    • @return 填充好的解析数据
      */
      private void explainMergeData(Map<Integer,Map<Integer, String>> data, List extraMergeInfoList) {
      //循环所有合并单元格信息
      extraMergeInfoList.forEach(cellExtra -> {
      int firstRowIndex = cellExtra.getFirstRowIndex();
      int lastRowIndex = cellExtra.getLastRowIndex();
      int firstColumnIndex = cellExtra.getFirstColumnIndex();
      int lastColumnIndex = cellExtra.getLastColumnIndex();

       Map<Integer,String> rdata = data.get(cellExtra.getRowIndex()) ;
       String val = null ;
       if(rdata != null){
           val = rdata.get(cellExtra.getColumnIndex()) ;
       }
       //遍历每行
       Map<Integer, String> rowData = null ;
       for(int i=firstRowIndex;i<=lastRowIndex;i++){
           rowData = data.get(i) ;
           if(rowData == null){
               continue;
           }
           for(int c = firstColumnIndex;c<=lastColumnIndex;c++){
               rowData.put(c,val) ;
           }
       }
      

      });
      }

    public static void main(String[] args) throws FileNotFoundException {
    //读取的表格名
    String fileName = “C:\Users\dsf\Desktop\解析的\2020年2季度电子渠道新业务开发需求-评估数据(数据导入模板).xlsx”;
    String fileName2 = “C:\Users\dsf\Desktop\解析的\非COSMIC评估工作量汇总模板.xlsx” ;
    String fileName3 = “C:\Users\dsf\Desktop\解析的\test.xlsx” ;
    EasyExcel.read(fileName3,new NoModelDataListener())
    .extraRead(CellExtraTypeEnum.MERGE) // 需要读取合并单元格信息 默认不读取
    //.registerConverter(new EmptyConverter()) //默认:DefaultConverterLoader#loadDefaultReadConverter()
    .ignoreEmptyRow(true)
    .autoTrim(true)
    .headRowNumber(1)
    .autoCloseStream(true)
    //.sheet(“2、功能点拆分表”)
    //.sheet(“4、结果计算”)
    .sheet()
    .doRead();

    }
    }

参考链接:https://blog.51cto.com/dengshuangfu/2566775

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值