java excel 合并单元格_java excel 合并单元格

本文介绍了如何使用Java的POI库来处理Excel的单元格合并,包括利用easy-poi和easy-excel的基本合并功能,以及通过自定义逻辑实现复杂情况的单元格合并。关键在于对数据进行分组并计算合并单元格的数量,然后通过Sheet的addMergedRegion方法完成合并。
摘要由CSDN通过智能技术生成

案例

Excel 导入导出,大部分使用 easy-poi 或者 easy-excel 两个工具类就可以了,对于简单的一行一行(像关系型数据库表记录)的导出那可真的是啪的一声,很快啊。

就像下图这样:

8f209e46c021

sheet1

可是要想导出成下图:

8f209e46c021

sheet2

这就有点难度了。

工具现成方法

easy-poi

easy-poi注解导出,@Excel 注解有个 needMerge 属性,属性描述:是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row),这个属性默认为false,若为true,则会将当前单元格与上一行同列单元格进行比较,如果一样,则会合并单元格,这样应付上图是可以的,但是要是跨列,好像就不支持了。

easy-excel

easy-excel 注解导出有个 @ContentLoopMerge 注解,表示每隔几列合并单元格,这样对于有固定规律的表格是没问题的,如果是 23333 这种,应该也就不支持了。

利用 poi Api 完成

思路

首先根据渲染的数据,根据需要合并的属性,进行分组,然后计算出,合并单元格数量

利用easy-poi 和 easy-excel 渲染 Excel ,获得 Workbook

再根据导出sheet名称,获取Sheet

利用Sheet#addMergedRegion方法进行合并

done

计算获得合并单元格

一般渲染都是list,可以利用 stream 操作进行 GroupBy

TreeMap> treeMap = list.stream()

.collect(Collectors.groupingBy(key,

() -> new TreeMap>(comparator),

Collectors.toList()));

List groups = Lists.newArrayList();

for (Map.Entry> entry : treeMap.entrySet()) {

groups.add(entry.getValue().size());

}

这里主要讲下,一定要用TreeMap这个结构,因为HashMap这种key是乱序的,一旦乱序,就会与已经导出的Excel不一致,一旦不一致,就是乱合并。

所以groupingBy的第二个参数里面的比较器就尤为重要了,一定要用比较器去控制排序与真实Excel一致。

分组完毕之后就是将,每个分组size记录下来,以便进行计算格子。

/**

* 计算合并格子

*

* @param startRow 表头最后行

* @param cols 需要合并的列 数组

* @return

*/

public List computeRange(int startRow, int[] cols) {

List mergeCell = Lists.newArrayList();

for (Integer group : this.groups) {

int interval = group;

if (interval == 1) {

startRow = startRow + 1;

continue;

}

int beginRow = startRow;

int endRow = beginRow + interval - 1;

for (int col : cols) {

CellRangeAddress range = singleRowCellRange(beginRow, endRow, col);

mergeCell.add(range);

}

startRow = endRow + 1;

}

return mergeCell;

}

每次只能计算一个合并列,需要过滤表头以及知道合并的列,计算获得一系列的CellRangeAddress

合并

Sheet sheet = workbook.getSheet(sheetName);

List addresses = ranges.get(sheetName);

for (CellRangeAddress cellAddresses : addresses) {

sheet.addMergedRegion(cellAddresses);

}

END

按照这个方法,基本上可以实现任意合并了,只是稍微有些繁琐。我自己整理了个工具方法,可以稍微简化下流程。

SheetMerge sheetMerge = new SheetMerge(list);

sheetMerge.range("test", TestEntity::getA, (a, b) -> CompareUtil.compare(a, b), new int[]{0}, 1);

ExportParams exportParams = new ExportParams();

exportParams.setSheetName("test");

Workbook workbook = ExcelExportUtil.exportExcel(exportParams, TestEntity.class, list);

sheetMerge.merge(workbook);

@Cleanup

BufferedOutputStream outputStream = FileUtil.getOutputStream(file_name);

workbook.write(outputStream);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值