EasyExcel合并单元格(同列相同数据合并)

在这里插入图片描述

合并后效果如下:
在这里插入图片描述
合并策略代码:

public class CustomMergeStrategy extends AbstractMergeStrategy {

	/**
	 * 分组,每几行合并一次
	 */
	private List<List<Integer>> mergeColDataGroupCountList;

	/**
	 * 目标合并列index
	 */
	private List<Integer> targetColumnIndex;
	/**
	 * 	需要开始合并单元格的首行index
 	 */
	private Integer rowIndex;

	/**
	 * 	mergeColDataList为待合并目标列的值
 	 */
	public CustomMergeStrategy(List<List<String>> mergeColDataList, List<Integer> targetColumnIndex) {
		this.mergeColDataGroupCountList = getGroupCountList(mergeColDataList);
		this.targetColumnIndex = targetColumnIndex;
	}


	@Override
	protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {

		if (null == rowIndex) {
			rowIndex = cell.getRowIndex();
		}
		// 仅从首行以及目标列的单元格开始合并,忽略其他
		if (cell.getRowIndex() == rowIndex && targetColumnIndex.contains(cell.getColumnIndex())) {
			//找到对应的需要合并的列
			AtomicInteger i = new AtomicInteger(0);
			Optional<Integer> first = targetColumnIndex.stream().filter(col -> {
				i.getAndIncrement();
				return col == cell.getColumnIndex();
			}).findFirst();
			mergeGroupColumn(sheet, first.get());
		}
	}

	private void mergeGroupColumn(Sheet sheet, Integer index) {
		int rowCount = rowIndex;
		for (Integer count : mergeColDataGroupCountList.get(index)) {
			if (count == 1) {
				rowCount += count;
				continue;
			}
			// 合并单元格
			CellRangeAddress cellRangeAddress = new CellRangeAddress(rowCount, rowCount + count - 1,
					targetColumnIndex.get(index), targetColumnIndex.get(index));
			sheet.addMergedRegionUnsafe(cellRangeAddress);
			rowCount += count;
		}
	}

	/**
	 * 	该方法将目标列根据值是否相同连续可合并,存储可合并的行数
 	 */
	private List<List<Integer>> getGroupCountList(List<List<String>> exportDataList) {
		if (CollUtil.isEmpty(exportDataList)) {
			return new ArrayList<>();
		}
		List<List<Integer>> groupCountListList = new ArrayList<>();
		exportDataList.forEach(dataList->{
			List<Integer> groupCountList = new ArrayList<>();
			int count = 1;
			for (int i = 1; i < dataList.size(); i++) {
				if (dataList.get(i).equals(dataList.get(i - 1))) {
					count++;
				} else {
					groupCountList.add(count);
					count = 1;
				}
			}
			// 处理完最后一条后
			groupCountList.add(count);
			groupCountListList.add(groupCountList);
		});
		return groupCountListList;
	}
}

使用:
step1:mergeColDataList——将准备插入Excel的数据中的“序号(num)”和“运营公司(operateDeptName)”两个字段收集起来,放到二维List中。
step2:mergeColIndexList——构造要合并的列index集合。

//序号列和运营公司列需要合并单元格
		List<List<String>> mergeColDataList = Stream.of(data.stream().map(BridgeTypeLengthExcel::getNum).collect(Collectors.toList()),
				data.stream().map(BridgeTypeLengthExcel::getOperateDeptName).collect(Collectors.toList())).collect(Collectors.toList());
		//第一列(index=0)和第二列(index=1)
		List<Integer> mergeColIndexList = Stream.of(0, 1).collect(Collectors.toList());
		//内部finish的时候会自动关闭流
		EasyExcel.write(response.getOutputStream(), BridgeTypeLengthExcel.class)
				.registerWriteHandler(
						new CustomMergeStrategy(
								mergeColDataList, mergeColIndexList
						)
				)
				.sheet("统计")
				.doWrite(data);

主体代码来自网络,按自己业务修改,支持多列相同数据合并。

  • 7
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值