Apache poi 对单元格进行合并

编程入门 行业动态 更新时间:2024-10-21 09:22:53

Apache poi 对<a href=https://www.elefans.com/category/jswz/34/1770080.html style=单元格进行合并"/>

Apache poi 对单元格进行合并

需求背景:

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

期望达到的效果:

poi 实现合并单元格的方法  

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

个人的实现思路:

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中存放 "营运",   在遍历的过程中, 我们需要判断当前行的单元格内容是否跟上一行的单元格内容相同, 如果相同, 我们此时就应该把坐标记录起来了, 可以存在到一个对象中

 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进行合并就达到这个效果了

代码实现:

/*** 构建需要合并单元格操作的对象信息* @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 对单元格进行合并

本文发布于:2024-02-27 05:04:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1705281.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:单元格   Apache   poi

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!