0%

POI操作EXCEL合并单元格

POI操作EXCEL合并单元格详解

在使用 POI 处理 Excel 时,合并单元格是常见需求,比如制作表头、合并相同内容的单元格等。下面详细介绍如何通过 POI 实现单元格合并,并补充相关注意事项。

核心类与方法

POI 中合并单元格的核心类是 CellRangeAddress,通过它定义需要合并的单元格范围,再调用工作表的 addMergedRegion 方法完成合并。

  • CellRangeAddress 构造方法
    用于定义合并的单元格区域,参数含义如下:

    1
    CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)
    • firstRow:起始行索引(从 0 开始)
    • lastRow:终止行索引(包含)
    • firstCol:起始列索引(从 0 开始)
    • lastCol:终止列索引(包含)
  • Sheet.addMergedRegion 方法
    将定义好的单元格范围添加到工作表中,完成合并:

    1
    sheet.addMergedRegion(cellRangeAddress);

示例代码

以下是一个完整的示例,演示如何在 Excel 中合并单元格(以 XSSF 为例,适用于.xlsx格式):

maven依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
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
63
64
65
66
67
68
69
70
71
72
73
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;

public class MergeCellsExample {
public static void main(String[] args) {
// 创建工作簿和工作表
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("合并单元格示例");

// 创建标题行,并合并单元格(A1到D1)
Row titleRow = sheet.createRow(0);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellValue("员工信息表");
// 合并第一行的第0列到第3列(A1-D1)
CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, 3);
sheet.addMergedRegion(titleRange);

// 合并其他单元格(例如:合并部门列中相同部门的单元格)
// 模拟数据:姓名、部门、职位、薪资
String[][] data = {
{"张三", "技术部", "开发工程师", "15000"},
{"李四", "技术部", "测试工程师", "12000"},
{"王五", "市场部", "市场专员", "10000"},
{"赵六", "市场部", "市场经理", "20000"}
};

// 写入表头(第二行)
Row headerRow = sheet.createRow(1);
String[] headers = {"姓名", "部门", "职位", "薪资"};
for (int i = 0; i < headers.length; i++) {
headerRow.createCell(i).setCellValue(headers[i]);
}

// 写入数据(从第三行开始)
for (int i = 0; i < data.length; i++) {
Row row = sheet.createRow(i + 2);
for (int j = 0; j < data[i].length; j++) {
row.createCell(j).setCellValue(data[i][j]);
}
}

// 合并部门列中相同的"技术部"(行2-3,列1)
CellRangeAddress techDeptRange = new CellRangeAddress(2, 3, 1, 1);
sheet.addMergedRegion(techDeptRange);

// 合并部门列中相同的"市场部"(行4-5,列1)
CellRangeAddress marketDeptRange = new CellRangeAddress(4, 5, 1, 1);
sheet.addMergedRegion(marketDeptRange);

// 调整列宽
for (int i = 0; i < 4; i++) {
sheet.autoSizeColumn(i);
}

// 保存文件
try (FileOutputStream fos = new FileOutputStream("员工信息表.xlsx")) {
workbook.write(fos);
System.out.println("Excel生成成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

注意事项

  1. 合并后的数据显示
    合并单元格后,只有左上角第一个单元格的数据会被保留,其他被合并的单元格数据会被覆盖。因此,需确保只在左上角单元格中设置值。

  2. 单元格样式
    合并后的单元格样式需单独设置(作用于左上角单元格),否则可能继承原单元格样式导致显示不一致。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    // 设置标题单元格样式(居中、加粗)
    CellStyle titleStyle = workbook.createCellStyle();
    Font titleFont = workbook.createFont();
    titleFont.setBold(true);
    titleStyle.setFont(titleFont);
    titleStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
    titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
    titleCell.setCellStyle(titleStyle);
  1. 版本兼容性

    • 对于 .xls 格式(Excel 2003 及以前),使用 HSSFWorkbookHSSFSheet
    • 对于 .xlsx 格式(Excel 2007 及以后),使用 XSSFWorkbookXSSFSheet
      两者的合并单元格方法完全一致,仅工作簿和工作表的类不同。
  2. 解除合并
    若需解除合并,可使用 Sheet.removeMergedRegion(int index) 方法,其中 index 是合并区域在工作表中的索引(可通过 Sheet.getNumMergedRegions() 获取总数)。

  3. 大数据量合并
    大量合并单元格可能影响 Excel 性能,建议仅在必要时使用,避免过度合并。

欢迎关注我的其它发布渠道