使用Apache POI在Java中實現(xiàn)Excel單元格的合并
在日常工作中,Excel 是一個不可或缺的工具,尤其是在處理大量數(shù)據(jù)時。為了提升數(shù)據(jù)的可讀性和美觀性,我們經(jīng)常需要對 Excel 中的單元格進(jìn)行合并操作。本文將介紹如何使用 Apache POI 庫在 Java 中實現(xiàn) Excel 單元格的合并,并提供一個現(xiàn)成的工具類供大家使用。
工具類介紹
我們提供了一個名為 ExcelMergeUtility 的工具類,它可以幫助你輕松地合并 Excel 中的單元格。該類支持縱向合并(按行合并)和橫向合并(按列合并),并且可以指定需要合并的列。
工具類代碼
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.springframework.stereotype.Component; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; @Component public class ExcelMergeUtility { /** * 合并Excel中內(nèi)容相同的單元格 * * @param workbook 工作簿 * @param sheetName 工作表名稱 * @param columnsToMerge 需要合并的列索引列表 * @param isRowMerge 是否按行合并(縱向合并) * @param isColumnMerge 是否按列合并(橫向合并) */ public void mergeCells(Workbook workbook, String sheetName, List<Integer> columnsToMerge, boolean isRowMerge, boolean isColumnMerge) { Sheet sheet = workbook.getSheet(sheetName); if (sheet == null) { throw new IllegalArgumentException("工作表 " + sheetName + " 不存在"); } // 記錄第一列的合并行數(shù) int firstColMergeEndRow = 0; for (int colIndex : columnsToMerge) { for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) { Row currentRow = sheet.getRow(rowIndex); if (currentRow == null) continue; Cell currentCell = currentRow.getCell(colIndex); if (currentCell == null) continue; String currentValue = currentCell.getStringCellValue(); if (isRowMerge) { // 縱向合并 int mergeStartRow = rowIndex; while (rowIndex + 1 <= sheet.getLastRowNum()) { Row nextRow = sheet.getRow(rowIndex + 1); if (nextRow == null) break; Cell nextCell = nextRow.getCell(colIndex); if (nextCell == null || !nextCell.getStringCellValue().equals(currentValue)) break; // 如果當(dāng)前列不是第一列,且合并行數(shù)超過前一列的合并行數(shù),則停止合并 if (colIndex > 0 && rowIndex + 1 > getMergeEndRow(sheet, mergeStartRow, colIndex - 1)) break; // 如果合并行數(shù)超過第一列的合并行數(shù),則停止合并 if (colIndex > 0 && rowIndex + 1 > firstColMergeEndRow) break; rowIndex++; } if (mergeStartRow != rowIndex) { sheet.addMergedRegion(new CellRangeAddress(mergeStartRow, rowIndex, colIndex, colIndex)); } // 如果是第一列,記錄合并的最后一行 if (colIndex == 0) { firstColMergeEndRow = rowIndex; } } if (isColumnMerge) { // 橫向合并 int mergeStartCol = colIndex; while (colIndex + 1 < currentRow.getLastCellNum()) { Cell nextCell = currentRow.getCell(colIndex + 1); if (nextCell == null || !nextCell.getStringCellValue().equals(currentValue)) break; colIndex++; } if (mergeStartCol != colIndex) { sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, mergeStartCol, colIndex)); } } } } } /** * 獲取指定單元格的合并的最后一行 * * @param sheet 工作表 * @param rowIndex 行索引 * @param colIndex 列索引 * @return 合并的最后一行 */ private int getMergeEndRow(Sheet sheet, int rowIndex, int colIndex) { int numMergedRegions = sheet.getNumMergedRegions(); for (int i = 0; i < numMergedRegions; i++) { CellRangeAddress mergedRegion = sheet.getMergedRegion(i); if (mergedRegion.isInRange(rowIndex, colIndex)) { return mergedRegion.getLastRow(); } } // for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) { // if (mergedRegion.isInRange(rowIndex, colIndex)) { // return mergedRegion.getLastRow(); // } // } return rowIndex; // 如果沒有合并,則返回當(dāng)前行 } /** * 示例:生成Excel并合并單元格 */ public void generateAndMergeExcel(String filePath, String sheetName, List<Integer> columnsToMerge, boolean isRowMerge, boolean isColumnMerge) throws IOException { // 打開現(xiàn)有的Excel文件 Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath)); // 合并單元格 mergeCells(workbook, sheetName, columnsToMerge, isRowMerge, isColumnMerge); // 寫入文件 try (FileOutputStream fileOut = new FileOutputStream(filePath)) { workbook.write(fileOut); } workbook.close(); } }
調(diào)用示例
List<Integer> columnsToMerge = Arrays.asList(0, 1, 2, 3, 4, 5); // 合并第1列和第2列 boolean isRowMerge = true; // 啟用縱向合并 boolean isColumnMerge = false; // 禁用橫向合并 excelMergeUtility.generateAndMergeExcel("C:\\Users\\xxxx\\Downloads\\匯總記錄2025-03-04%2B10_38_30.xls", "匯總", columnsToMerge, isRowMerge, isColumnMerge);
依賴配置
為了使用這個工具類,你需要在你的項目中添加 Apache POI 的依賴:
<!-- Apache POI 核心庫 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <!-- Apache POI OOXML 庫,用于處理 .xlsx 文件 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency>
總結(jié)
通過 ExcelMergeUtility
工具類,你可以輕松地實現(xiàn) Excel 單元格的合并操作。無論是縱向合并還是橫向合并,該工具類都能滿足你的需求。
到此這篇關(guān)于使用Apache POI在Java中實現(xiàn)Excel單元格的合并的文章就介紹到這了,更多相關(guān)Apache POI合并Excel單元格內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
BigDecimal的toString()、toPlainString()和toEngineeringString()區(qū)
使用BigDecimal進(jìn)行打印的時候,經(jīng)常會對BigDecimal提供的三個toString方法感到好奇,以下整理3個toString方法的區(qū)別及用法,需要的朋友可以參考下2023-08-08springboot日期轉(zhuǎn)換器實現(xiàn)實例解析
這篇文章主要介紹了springboot日期轉(zhuǎn)換器實現(xiàn)實例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12解決RestTemplate 請求url中包含百分號 會被轉(zhuǎn)義成25的問題
這篇文章主要介紹了解決RestTemplate 請求url中包含百分號 會被轉(zhuǎn)義成25的問題,具有很好的參考價值,希望對大家有所幫助。2021-10-10Java并發(fā)編程:volatile關(guān)鍵字詳細(xì)解析
這篇文章主要介紹了Java并發(fā)編程:volatile關(guān)鍵字詳細(xì)解析,對學(xué)習(xí)volatile關(guān)鍵字有一定的認(rèn)識,有需要的可以了解一下。2016-11-11