使用 Apache POI 实现 Excel 单元格归并

打印 上一主题 下一主题

主题 914|帖子 914|积分 2742

在一样平常工作中,Excel 是一个不可或缺的工具,尤其是在处置惩罚大量数据时。为了提拔数据的可读性和雅观性,我们经常必要对 Excel 中的单元格进行归并操作。本文将介绍如何使用 Apache POI 库在 Java 中实现 Excel 单元格的归并,并提供一个现成的工具类供大家使用。
工具类介绍

我们提供了一个名为 ExcelMergeUtility 的工具类,它可以资助你轻松地归并 Excel 中的单元格。该类支持纵向归并(按行归并)和横向归并(按列归并),而且可以指定必要归并的列。
工具类代码

  1. import org.apache.poi.ss.usermodel.*;
  2. import org.apache.poi.ss.util.CellRangeAddress;
  3. import org.springframework.stereotype.Component;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.util.List;
  8. @Component
  9. public class ExcelMergeUtility {
  10.     /**
  11.      * 合并Excel中内容相同的单元格
  12.      *
  13.      * @param workbook       工作簿
  14.      * @param sheetName      工作表名称
  15.      * @param columnsToMerge 需要合并的列索引列表
  16.      * @param isRowMerge     是否按行合并(纵向合并)
  17.      * @param isColumnMerge  是否按列合并(横向合并)
  18.      */
  19.     public void mergeCells(Workbook workbook, String sheetName, List<Integer> columnsToMerge,
  20.                            boolean isRowMerge, boolean isColumnMerge) {
  21.         Sheet sheet = workbook.getSheet(sheetName);
  22.         if (sheet == null) {
  23.             throw new IllegalArgumentException("工作表 " + sheetName + " 不存在");
  24.         }
  25.         // 记录第一列的合并行数
  26.         int firstColMergeEndRow = 0;
  27.         for (int colIndex : columnsToMerge) {
  28.             for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
  29.                 Row currentRow = sheet.getRow(rowIndex);
  30.                 if (currentRow == null) continue;
  31.                 Cell currentCell = currentRow.getCell(colIndex);
  32.                 if (currentCell == null) continue;
  33.                 String currentValue = currentCell.getStringCellValue();
  34.                 if (isRowMerge) {
  35.                     // 纵向合并
  36.                     int mergeStartRow = rowIndex;
  37.                     while (rowIndex + 1 <= sheet.getLastRowNum()) {
  38.                         Row nextRow = sheet.getRow(rowIndex + 1);
  39.                         if (nextRow == null) break;
  40.                         Cell nextCell = nextRow.getCell(colIndex);
  41.                         if (nextCell == null || !nextCell.getStringCellValue().equals(currentValue)) break;
  42.                         // 如果当前列不是第一列,且合并行数超过前一列的合并行数,则停止合并
  43.                         if (colIndex > 0 && rowIndex + 1 > getMergeEndRow(sheet, mergeStartRow, colIndex - 1)) break;
  44.                         // 如果合并行数超过第一列的合并行数,则停止合并
  45.                         if (colIndex > 0 && rowIndex + 1 > firstColMergeEndRow) break;
  46.                         rowIndex++;
  47.                     }
  48.                     if (mergeStartRow != rowIndex) {
  49.                         sheet.addMergedRegion(new CellRangeAddress(mergeStartRow, rowIndex, colIndex, colIndex));
  50.                     }
  51.                     // 如果是第一列,记录合并的最后一行
  52.                     if (colIndex == 0) {
  53.                         firstColMergeEndRow = rowIndex;
  54.                     }
  55.                 }
  56.                 if (isColumnMerge) {
  57.                     // 横向合并
  58.                     int mergeStartCol = colIndex;
  59.                     while (colIndex + 1 < currentRow.getLastCellNum()) {
  60.                         Cell nextCell = currentRow.getCell(colIndex + 1);
  61.                         if (nextCell == null || !nextCell.getStringCellValue().equals(currentValue)) break;
  62.                         colIndex++;
  63.                     }
  64.                     if (mergeStartCol != colIndex) {
  65.                         sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, mergeStartCol, colIndex));
  66.                     }
  67.                 }
  68.             }
  69.         }
  70.     }
  71.     /**
  72.      * 获取指定单元格的合并的最后一行
  73.      *
  74.      * @param sheet     工作表
  75.      * @param rowIndex  行索引
  76.      * @param colIndex  列索引
  77.      * @return 合并的最后一行
  78.      */
  79.       private int getMergeEndRow(Sheet sheet, int rowIndex, int colIndex) {
  80.         int numMergedRegions = sheet.getNumMergedRegions();
  81.         for (int i = 0; i < numMergedRegions; i++) {
  82.             CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
  83.             if (mergedRegion.isInRange(rowIndex, colIndex)) {
  84.                 return mergedRegion.getLastRow();
  85.             }
  86.         }
  87. //        for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
  88. //            if (mergedRegion.isInRange(rowIndex, colIndex)) {
  89. //                return mergedRegion.getLastRow();
  90. //            }
  91. //        }
  92.         return rowIndex; // 如果没有合并,则返回当前行
  93.     }
  94.     /**
  95.      * 示例:生成Excel并合并单元格
  96.      */
  97.     public void generateAndMergeExcel(String filePath, String sheetName, List<Integer> columnsToMerge,
  98.                                       boolean isRowMerge, boolean isColumnMerge) throws IOException {
  99.         // 打开现有的Excel文件
  100.         Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));
  101.         // 合并单元格
  102.         mergeCells(workbook, sheetName, columnsToMerge, isRowMerge, isColumnMerge);
  103.         // 写入文件
  104.         try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
  105.             workbook.write(fileOut);
  106.         }
  107.         workbook.close();
  108.     }
  109. }
复制代码
调用示例

  1. List<Integer> columnsToMerge = Arrays.asList(0, 1, 2, 3, 4, 5); // 合并第1列和第2列
  2. boolean isRowMerge = true; // 启用纵向合并
  3. boolean isColumnMerge = false; // 禁用横向合并
  4. excelMergeUtility.generateAndMergeExcel("C:\\Users\\xxxx\\Downloads\\汇总记录2025-03-04%2B10_38_30.xls", "汇总", columnsToMerge, isRowMerge, isColumnMerge);
复制代码
依赖配置

为了使用这个工具类,你必要在你的项目中添加 Apache POI 的依赖:
  1. <!-- Apache POI 核心库 -->
  2. <dependency>
  3.     <groupId>org.apache.poi</groupId>
  4.     <artifactId>poi</artifactId>
  5.     <version>4.1.2</version>
  6. </dependency>
  7. <!-- Apache POI OOXML 库,用于处理 .xlsx 文件 -->
  8. <dependency>
  9.     <groupId>org.apache.poi</groupId>
  10.     <artifactId>poi-ooxml</artifactId>
  11.     <version>4.1.2</version>
  12. </dependency>
复制代码


总结

通过 ExcelMergeUtility 工具类,你可以轻松地实现 Excel 单元格的归并操作。无论是纵向归并还是横向归并,该工具类都能满足你的需求。盼望本文对你有所资助,欢迎在评论区分享你的使用体验和问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美食家大橙子

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表