# merge

# 基本合并操作

在使用 SXSSFWorkbook 合并单元格时,你可以通过 Sheet.addMergedRegion() 方法实现。虽然 SXSSFWorkbook 是针对大数据的流式写入版本,但其核心功能和 XSSFWorkbook 类似,包括单元格合并等操作。

下面是一个示例代码,展示如何在 SXSSFWorkbook 中合并单元格:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class SXSSFWorkbookMergeCellsExample {
    public static void main(String[] args) {
        // 创建 SXSSFWorkbook 工作簿
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        
        // 创建工作表
        Sheet sheet = workbook.createSheet("Example Sheet");

        // 创建行
        Row row = sheet.createRow(0);

        // 创建单元格并设置值
        Cell cell = row.createCell(0);
        cell.setCellValue("Merged Cell");

        // 合并单元格 (第一行和第一列到第一行和第三列)
        // 参数为:起始行号, 结束行号, 起始列号, 结束列号(索引从 0 开始)
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 2));

        // 保存 Excel 文件(这里省略保存逻辑,您可以根据需要保存文件)
        // FileOutputStream out = new FileOutputStream("example.xlsx");
        // workbook.write(out);
        // out.close();
        
        // 关闭工作簿以释放内存
        workbook.dispose();  // SXSSFWorkbook 使用后需要显式释放资源
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 代码说明:

  1. 创建 SXSSFWorkbook:创建一个 SXSSFWorkbook 实例,它是用于处理大数据的流式 Excel 文件生成类。
  2. 添加单元格数据:为单元格设置内容。
  3. 合并单元格:通过 sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startCol, endCol)) 来合并单元格。
    • 这里 CellRangeAddress 用来定义要合并的区域,参数分别是起始行号、结束行号、起始列号、结束列号。索引从 0 开始。
  4. 保存文件:可以根据需要使用 FileOutputStream 将文件保存到本地。
  5. 释放资源:由于 SXSSFWorkbook 会创建临时文件来处理大数据,使用完成后需要通过 workbook.dispose() 方法来显式释放资源和删除临时文件。

# 注意:

  • SXSSFWorkbook 主要用于写入大文件,因此它不支持随机访问已写入的行或列。合并操作需要在行和列写入时处理好。
  • 合并单元格必须在填充数据之前或之后处理,但不要在已写入的内容中修改同一区域,否则可能会丢失数据。

在使用 SXSSFWorkbook 动态合并行时,可以根据列中的数据相同的单元格来动态合并行。为了实现这个功能,你可以遍历整个工作表中的数据,并判断相邻行中某一列的数据是否相同,然后动态调用 Sheet.addMergedRegion() 来合并这些行。

下面是一个示例代码,展示如何根据数据信息相同来动态合并行:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class DynamicRowMergeExample {
    public static void main(String[] args) {
        // 创建 SXSSFWorkbook 工作簿
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        
        // 创建工作表
        Sheet sheet = workbook.createSheet("Example Sheet");

        // 创建一些示例数据
        String[][] data = {
            {"A", "Item 1"},
            {"A", "Item 2"},
            {"B", "Item 3"},
            {"B", "Item 4"},
            {"B", "Item 5"},
            {"C", "Item 6"}
        };

        // 填充数据到表格
        for (int i = 0; i < data.length; i++) {
            Row row = sheet.createRow(i);
            row.createCell(0).setCellValue(data[i][0]);
            row.createCell(1).setCellValue(data[i][1]);
        }

        // 动态合并根据第一列相同的数据
        int startRow = 0;  // 合并的起始行
        String previousValue = data[0][0];  // 记录第一列的初始值

        for (int i = 1; i < data.length; i++) {
            String currentValue = data[i][0];
            
            // 如果当前值和前一个值相同,继续合并
            if (currentValue.equals(previousValue)) {
                // 如果是最后一行,完成合并
                if (i == data.length - 1) {
                    sheet.addMergedRegion(new CellRangeAddress(startRow, i, 0, 0));
                }
            } else {
                // 如果当前值和前一个值不同,合并之前的行,并更新起始行
                if (startRow != i - 1) {
                    sheet.addMergedRegion(new CellRangeAddress(startRow, i - 1, 0, 0));
                }
                // 更新起始行和前一个值
                startRow = i;
                previousValue = currentValue;
            }
        }

        // 保存 Excel 文件(这里省略保存逻辑,您可以根据需要保存文件)
        // FileOutputStream out = new FileOutputStream("example.xlsx");
        // workbook.write(out);
        // out.close();
        
        // 关闭工作簿以释放内存
        workbook.dispose();  // SXSSFWorkbook 使用后需要显式释放资源
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

# 动态合并

# 代码说明:

  1. 数据填充:首先,创建了一个二维数组 data,其中每行包含两列数据。第一列用于动态判断是否要合并相邻的行,第二列作为示例内容。

  2. 动态合并逻辑

    • startRow 记录合并的起始行,previousValue 记录上一行的值。
    • 遍历每一行数据,如果当前行的第一列值与上一行相同,则跳过合并操作,直到发现不同的值时合并前面的行。
    • 当值不同或到达最后一行时,调用 sheet.addMergedRegion() 合并之前相同的数据行。
    • CellRangeAddress 用于指定需要合并的区域,参数为起始行、结束行、起始列、结束列。
  3. 保存文件:实际使用时,可以通过 FileOutputStream 将工作簿保存到文件。此处省略了保存的部分。

  4. 释放资源:由于使用了 SXSSFWorkbook,完成后要调用 workbook.dispose() 来释放内存并删除临时文件。

# 合并逻辑解释:

  • 如果相邻行的第一列数据相同,则合并这些行的第一列单元格。
  • 遍历整个数据集,动态判断是否需要合并,并根据结果设置 startRowpreviousValue 来调整合并范围。

通过这种方式,你可以根据数据的相同之处,动态合并行并保持数据表的简洁性和可读性。