1. 概述

本文将演示如何使用 Apache POI 在 Excel 中合并单元格。这是处理导出报表、生成统计表格等场景中非常常见的需求,比如需要一个跨列的标题栏。掌握这个技巧能让你的 Excel 输出更专业,避免踩坑时一脸懵。

2. Apache POI 基础依赖与模型

要使用 Apache POI 操作 Excel,首先得引入核心依赖。如果你用的是 Maven 项目,直接在 pom.xml 中添加:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>

Apache POI 使用一套清晰的接口模型来表示 Excel 的结构:

  • Workbook:代表整个 Excel 文件(.xlsx 或 .xls)
  • Sheet:代表工作簿中的一个工作表(如 Sheet1)
  • Row:代表某一行
  • Cell:代表单元格

理解这四个核心概念是操作 Excel 的基础,老手都懂,不多解释。

3. 合并单元格的实现方式

在 Excel 中,我们经常需要让文本跨多个单元格显示,比如一个标题横跨前三列。效果如下图所示:

merge

要实现这种效果,关键在于 Sheet 接口提供的 addMergedRegion() 方法,配合 CellRangeAddress 定义合并区域。

3.1 使用行列索引定义合并区域

最常用的方式是通过起始行、结束行、起始列、结束列的索引(从 0 开始)来指定范围:

Sheet sheet = // 已创建或获取的 Sheet 实例

int firstRow = 0;     // 第1行(索引0)
int lastRow = 0;      // 到第1行结束
int firstCol = 0;     // 从第1列(A列)开始
int lastCol = 2;      // 到第3列(C列)结束

sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));

上面这段代码会将 A1:C1 这个范围的三个单元格合并成一个。

3.2 使用 Excel 引用字符串定义区域

另一种更直观的方式是直接使用 Excel 风格的区域引用字符串:

Sheet sheet = // 已创建或获取的 Sheet 实例

sheet.addMergedRegion(CellRangeAddress.valueOf("A1:C1"));

✅ 这种写法可读性更强,尤其适合配置化场景或动态拼接区域。

⚠️ 注意事项:

  • 数据丢失风险:如果被合并的单元格中已有数据,Apache POI 会保留左上角单元格的值,其余单元格的数据将被丢弃。
  • 禁止区域重叠:不能添加相互重叠的合并区域,否则运行时会抛出异常(如 IllegalArgumentException),这点在循环生成合并区域时尤其容易踩坑。
  • ✅ 建议在写入数据后再执行合并操作,避免因顺序问题导致内容丢失。

4. 总结

本文介绍了使用 Apache POI 合并 Excel 单元格的两种方式:

  • 使用 CellRangeAddress 构造函数传入行列索引
  • 使用 CellRangeAddress.valueOf() 解析 Excel 区域字符串

两种方法本质相同,选择哪种取决于你的编码风格和使用场景。推荐在模板化导出中使用字符串方式,更清晰;在动态计算列宽时用索引方式更灵活。

示例代码已上传至 GitHub:https://github.com/dev-example/tutorials/tree/master/apache-poi


原始标题:Merge Cells in Excel Using Apache POI