Apache poi 对单元格进行合并

Apache poi 对单元格进行合并Apachepoi 对单元格进行合并 poi 合并单元格

大家好,欢迎来到IT知识分享网。

需求背景:

在导出excel时, 需要对内容相同的单元格进行纵向合并

期望达到的效果:

Apache poi 对单元格进行合并

poi 实现合并单元格的方法  

sheet.addMergedRegion(new CellRangeAddress(开始行, 结束行, 开始列, 结束列));

Apache poi 对单元格进行合并

Apache poi 对单元格进行合并

个人的实现思路:

1): 举个列子, 就拿截图贴出的 [公司类别] 这一列来进行说明

这个 [公司类别] 一共有 (营运 和 营销) 这两个不同的内容,  我们需要实现的效果是, 如果上下两行的内容是一致的话, 就需要对单元格进行合并

2): 在同列不同行的背景下, 获取到内容相同的单元格坐标, 这里的坐标有 #1合并单元格所需的开始行(也就是你这个单元格需要从第几行开始合并)  #2 合并单元格所需的结束行(也就是你这个单元格需要从第几行结束合并)  #3: 需要对哪一列的数据进行合并  (因为我们这里是纵向合并, 所以firstCol 和 lastCol 都是同一个)     ps: 在poi中, 行和列的索引都是从0开始,  也就是Excel中的[A]列对应poi的0列,   [1]行对应的是0行

3): 在我截图发出的excel中,  B列的3到15行内容都是 [营运], B列的16到25行都是[营销],  那么我们就需要计算出他们在poi中对应的坐标,  也就是1列的2到14行是[营运], 1列的15到24行是[营销],  只要我们能够清楚的获取到这个坐标信息, 就可以对单元格进行合并了

那么我是怎么判断出excel单元格中, 上下两行的数据是否一致呢?

1):  我们写入excel数据的时候, 其实会对sql查询出来的结果数据进行遍历, 然后依次写入excel中, 那么我们在遍历的过程中, 可以把相同列的数据存在起来, 定义两个List<String>  分别存放上一行的单元格内容 (perColList),  和当前当的单元格内容 (currentColList)   记住这里的List是有序的, 会记录添加顺序

用一个Map<String,List<String>>装起来, Map的key是列的坐标(加入是B列, 对应存放的就是1),  Map的Value是B列每一行的单元格数据

2):

此时开始数据的遍历, 当我们在遍历到Excel中的第三行A列的时候, 此时我们就需要获取到第二行的数据, 因为第二行的数据并不是我们sql结果集中的数据, 所以我们可以在perColList中默认存放一个空的字符串, 然后在currentColList中存放 “10”,    遍历到第三行B列的时候, perColList存放空字符串, currentColList中存放 “营运”,   在遍历的过程中, 我们需要判断当前行的单元格内容是否跟上一行的单元格内容相同, 如果相同, 我们此时就应该把坐标记录起来了, 可以存在到一个对象中

Apache poi 对单元格进行合并

 3): 当我们在遍历到第四行当时候, 此时我们这个对象就是  firstRow=2   lastRow=3  firstCol=1  lastCol=1   重点来了, 遍历到第五行的时候, 因为第四行的数据跟第五行的也一致, 那么我们此时就需要把对象里面的 lastRow 替换成 4,  直到遍历到第16行, 此时这个对象就应该是 firstRow=2   lastRow=15  firstCol=1  lastCol=1 

4): 现在程序遍历到第17行, 因为此时的B列内容变成了(营销),  那么当前行的内容跟上一行的内容不一致,  此时我们这里就需要构建新的对象了,  把之前我们构建好的那个 lastRow=15 的营运对象存放起来, 放到一个List中,  然后再重新构建这个单元格合并对象

5): 此时程序遍历到25行, 对象就是 firstRow=15   lastRow=24  firstCol=1  lastCol=1,  遍历到第26行当时候, 发现内容又不相同了, 就得重复之前的操作, 把 lastRow=24 的对象存在到List中, 开始构建新的单元格合并对象,  以此类推 , 最后我们的List中就会存在多个单元格合并对象,   然后我们头通过调用poi合并单元格的方法, 对这个List进行合并就达到这个效果了

代码实现:

Apache poi 对单元格进行合并

Apache poi 对单元格进行合并

/ * 构建需要合并单元格操作的对象信息 * @param resultMergedColList 存在需要进行合并的单元格对象(最终结果) * @param mergedColMaps Key:excel的第几列 Value:合并单元格对象 * @param currentRow 当前行 * @param currentRowValue 当前行的值 * @param preRow 上一行 * @param preRowValue 上一行的值 * @param colNum 第几列 */ private static void buildPoiMergedSameColInfo(List<PoiMergedSameCol> resultMergedColList, Map<Integer, List<PoiMergedSameCol>> mergedColMaps, Integer currentRow, String currentRowValue, Integer preRow, String preRowValue, int colNum) { if (StringUtils.isNotBlank(currentRowValue) && StringUtils.isNotBlank(preRowValue) && currentRowValue.equals(preRowValue)) { List<PoiMergedSameCol> poiMergedSameCols = mergedColMaps.get(colNum); if (CollectionUtils.isEmpty(poiMergedSameCols)) { PoiMergedSameCol poiMergedSameCol = new PoiMergedSameCol(); poiMergedSameCol.setFirstRow(preRow); poiMergedSameCol.setLastRow(currentRow); poiMergedSameCol.setFirstCol(colNum); mergedColMaps.put(colNum, Lists.newArrayList(poiMergedSameCol)); } else { Boolean existFlag = false; for (PoiMergedSameCol col : poiMergedSameCols) { if (preRow.equals(col.getLastRow())) { col.setLastRow(currentRow); existFlag = true; } } if (!existFlag) { //将之前生成的需要合并的单元格数据保存 resultMergedColList.addAll(mergedColMaps.get(colNum)); //构建新的需要保存的单元格数据 PoiMergedSameCol poiMergedSameCol = new PoiMergedSameCol(); poiMergedSameCol.setFirstRow(preRow); poiMergedSameCol.setLastRow(currentRow); poiMergedSameCol.setFirstCol(colNum); mergedColMaps.put(colNum, Lists.newArrayList(poiMergedSameCol)); } } } }

Apache poi 对单元格进行合并

这只是个人的解决思路, 如果有更好的方法也大家也可以一起分享下

觉得文章不错的话, 麻烦点赞收藏啦

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120050.html

(0)
上一篇 2025-11-01 10:33
下一篇 2025-11-01 10:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信