最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Apache POI在Java中實(shí)現(xiàn)Excel單元格的合并

 更新時(shí)間:2025年03月05日 15:04:02   作者:好奇的菜鳥  
在日常工作中,Excel是一個(gè)不可或缺的工具,尤其是在處理大量數(shù)據(jù)時(shí),本文將介紹如何使用 Apache POI 庫(kù)在 Java 中實(shí)現(xiàn) Excel 單元格的合并,需要的可以了解下

在日常工作中,Excel 是一個(gè)不可或缺的工具,尤其是在處理大量數(shù)據(jù)時(shí)。為了提升數(shù)據(jù)的可讀性和美觀性,我們經(jīng)常需要對(duì) Excel 中的單元格進(jìn)行合并操作。本文將介紹如何使用 Apache POI 庫(kù)在 Java 中實(shí)現(xiàn) Excel 單元格的合并,并提供一個(gè)現(xiàn)成的工具類供大家使用。

工具類介紹

我們提供了一個(gè)名為 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ù)超過(guò)前一列的合并行數(shù),則停止合并
                        if (colIndex > 0 && rowIndex + 1 > getMergeEndRow(sheet, mergeStartRow, colIndex - 1)) break;

                        // 如果合并行數(shù)超過(guò)第一列的合并行數(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; // 如果沒(méi)有合并,則返回當(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);

依賴配置

為了使用這個(gè)工具類,你需要在你的項(xiàng)目中添加 Apache POI 的依賴:

<!-- Apache POI 核心庫(kù) -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<!-- Apache POI OOXML 庫(kù),用于處理 .xlsx 文件 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

總結(jié)

通過(guò) ExcelMergeUtility 工具類,你可以輕松地實(shí)現(xiàn) Excel 單元格的合并操作。無(wú)論是縱向合并還是橫向合并,該工具類都能滿足你的需求。

到此這篇關(guān)于使用Apache POI在Java中實(shí)現(xiàn)Excel單元格的合并的文章就介紹到這了,更多相關(guān)Apache POI合并Excel單元格內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java設(shè)置千分位分隔符的兩種方法

    Java設(shè)置千分位分隔符的兩種方法

    在 Java 中,有時(shí)候我們需要對(duì)數(shù)字進(jìn)行千分位分隔,以提升數(shù)字的可讀性,本文將介紹如何在 Java 中實(shí)現(xiàn)對(duì)數(shù)字設(shè)置千分位分隔符的方法,需要的朋友可以參考下
    2024-10-10
  • JVM內(nèi)存結(jié)構(gòu):程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧

    JVM內(nèi)存結(jié)構(gòu):程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧

    JVM 基本上是每家招聘公司都會(huì)問(wèn)到的問(wèn)題,它們會(huì)這么無(wú)聊問(wèn)這些不切實(shí)際的問(wèn)題嗎?很顯然不是。由 JVM 引發(fā)的故障問(wèn)題,無(wú)論在我們開發(fā)過(guò)程中還是生產(chǎn)環(huán)境下都是非常常見的
    2021-06-06
  • spring中ioc是什么

    spring中ioc是什么

    IoC是一種讓服務(wù)消費(fèi)者不直接依賴于服務(wù)提供者的組件設(shè)計(jì)方式,是一種減少類與類之間依賴的設(shè)計(jì)原則。下面通過(guò)本文給大家分享spring中ioc的概念,感興趣的朋友一起看看吧
    2017-09-09
  • SpringBoot3安全管理操作方法

    SpringBoot3安全管理操作方法

    這篇文章主要介紹了SpringBoot3安全管理,在實(shí)際開發(fā)中,最常用的是登錄驗(yàn)證和權(quán)限體系兩大功能,在登錄時(shí)完成身份的驗(yàn)證,加載相關(guān)信息和角色權(quán)限,在訪問(wèn)其他系統(tǒng)資源時(shí),進(jìn)行權(quán)限的驗(yàn)證,保護(hù)系統(tǒng)的安全,文中有詳細(xì)的操作步驟,需要的朋友可以參考下
    2023-08-08
  • MacBook Java開發(fā)環(huán)境搭建的詳細(xì)步驟(新手必備)

    MacBook Java開發(fā)環(huán)境搭建的詳細(xì)步驟(新手必備)

    本文主要介紹了MacBook Java開發(fā)環(huán)境搭建,文中通過(guò)圖文示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Windows環(huán)境IDEA下Ranger1.2.0源碼編譯詳細(xì)流程

    Windows環(huán)境IDEA下Ranger1.2.0源碼編譯詳細(xì)流程

    本文給大家講解Windows環(huán)境IDEA下Ranger1.2.0源碼編譯過(guò)程,通過(guò)配置Tomcat,發(fā)布?security-admin-web項(xiàng)目,編譯啟動(dòng)tomcat即可完成,需要的朋友參考下
    2021-06-06
  • 在java程序中使用protobuf

    在java程序中使用protobuf

    這篇文章主要介紹了protobuf的基本使用和同java結(jié)合的具體案例,感性興趣的小伙伴可以一起來(lái)閱讀下文
    2021-08-08
  • Java通過(guò)值查找對(duì)應(yīng)的枚舉的實(shí)現(xiàn)

    Java通過(guò)值查找對(duì)應(yīng)的枚舉的實(shí)現(xiàn)

    本文主要介紹了Java通過(guò)值查找對(duì)應(yīng)的枚舉的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • java對(duì)JSON字符串差異化對(duì)比分析

    java對(duì)JSON字符串差異化對(duì)比分析

    文章介紹了兩種對(duì)比Java中JSON字符串差異的方法:使用Jackson包通過(guò)自定義過(guò)濾規(guī)則和使用json-patch庫(kù),前者可以自定義對(duì)比規(guī)則,而后者具有更好的擴(kuò)展性,文中提供了實(shí)操示例并總結(jié)了經(jīng)驗(yàn)
    2026-03-03
  • java實(shí)現(xiàn)輸出字符串中第一個(gè)出現(xiàn)不重復(fù)的字符詳解

    java實(shí)現(xiàn)輸出字符串中第一個(gè)出現(xiàn)不重復(fù)的字符詳解

    這篇文章主要介紹了java實(shí)現(xiàn)輸出字符串中第一個(gè)出現(xiàn)不重復(fù)的字符詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04

最新評(píng)論

治县。| 华容县| 西林县| 天门市| 南江县| 台北县| 邛崃市| 开封市| 盐源县| 兴仁县| 池州市| 张家口市| 肃北| 凯里市| 寿光市| 尼勒克县| 运城市| 清镇市| 分宜县| 南投县| 商城县| 贵南县| 金塔县| 北宁市| 禹州市| 泸西县| 青州市| 隆安县| 太仓市| 华安县| 民权县| 马山县| 南木林县| 荔浦县| 密云县| 渝中区| 迁安市| 方正县| 泗阳县| 宁海县| 新河县|