【工作中碰到Excel】EasyExcel-合并单元格读取

tip:这块合并我是按照我们项目中所涉及的excel编写的逻辑,没做大量测试,仅供参考。

读取的数据:

在这里插入图片描述
我们希望每一行都能读取为类似的Map:
{“0”:“123”,“1”:“北京”,“2”:“京1”,“3”:“J1”,“4”:“>5”,“5”:“>5”}
但是如果不进行合并单元格处理,只能读成:
在这里插入图片描述

在读取代码中加入extraRead,读取合并

在这里插入图片描述

在监听器中,编写方法,读取合并的信息:

@Getter
public class ReadMergeAsMapListener extends AnalysisEventListener<Map<String, Object>> {

    private final List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();

    private final List<CellExtra> extraList = new ArrayList<CellExtra>();

    public void invoke(Map<String, Object> data, AnalysisContext context) {
        dataList.add(data);
    }

    public void extra(CellExtra extra, AnalysisContext context) {
        CellExtraTypeEnum type = extra.getType();
        // 合并
        if (type.equals(CellExtraTypeEnum.MERGE)){
            extraList.add(extra);
        }
    }

    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("read finish");
    }
}

打印出合并的信息,可以得到合并的单元格信息:
在这里插入图片描述

通过这个json,并观察excel,
我们可以判断:rowIndex、columnIndex指的是在excel中的坐标,

带first的两组代表的是,从first到last的单元格是合并的。

接下来我们再根据读取出来的dataList对数据进行填补。
(其实可以判断出来,这个rowIndex,columnIndex可以处理成对应的 dataList信息)

由于这个extraList是读取的所有数据包括表头,而dataList会去掉表头,
所以我们要认为规定实际数据的起点,也就是数据开始的行数(从0开始数)
例如这个excel,headRow就是2。

编写合并逻辑

    private static void fillDataListByMerge(List<Map<Integer, Object>> dataList, List<CellExtra> extraList, Integer headRow) {
        for (CellExtra cellExtra : extraList) {
            Integer rowIndex = cellExtra.getRowIndex();
            if (rowIndex < headRow){
                continue;
            }
            int dataListIndex = rowIndex - headRow;
            Integer dataMapKey = cellExtra.getColumnIndex();
            Map<Integer, Object> dataMap = dataList.get(dataListIndex);
            Integer firstRowIndex = cellExtra.getFirstRowIndex() - headRow;
            Integer lastRowIndex = cellExtra.getLastRowIndex() - headRow;
            Integer firstColumnIndex = cellExtra.getFirstColumnIndex();
            Integer lastColumnIndex = cellExtra.getLastColumnIndex();
            Object value = dataMap.get(dataMapKey);
            // 左右合并
            for (int i = firstColumnIndex + 1; i < lastColumnIndex + 1; i++) {
                dataMap.put(i, value);
            }
            // 上下合并
            for (int i = firstRowIndex + 1; i < lastRowIndex + 1; i++) {
                Map<Integer, Object> integerObjectMap = dataList.get(i);
                integerObjectMap.put(firstColumnIndex, value);
                if (!firstColumnIndex.equals(lastColumnIndex)){
                    for (int j = firstColumnIndex + 1; j < lastColumnIndex + 1; j++) {
                        integerObjectMap.put(j, value);
                    }
                }
            }
        }
    }

合并结果:
在这里插入图片描述

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值