1. 概述

本文将通过一个简单示例,介绍如何使用 Apache POI 在 Java 中为 Excel 表格的单元格设置公式。✅

目标很明确:动态写入公式并触发计算,最终生成可直接在 Excel 中查看结果的文件。这类需求在报表生成、数据导出等场景中非常常见,属于“踩坑”高频区,掌握核心套路能少走很多弯路。

2. Apache POI 简介

Apache POI 是 Java 领域处理 Microsoft Office 文件(尤其是 Excel)的事实标准开源库。它支持创建、修改和读取 .xls.xlsx 格式文件。

核心概念:

  • Workbook:代表一个 Excel 文件
  • Sheet:工作表
  • RowCell:行与单元格
  • 单元格类型支持 FORMULA,即可以存储公式而非静态值

我们以一个实际场景为例:给定一个包含 A、B 两列数值的 Excel 文件,我们希望在 C 列插入一个公式,计算 SUM(A:A) - SUM(B:B)

原始数据如下图所示:

Sample Excel File

3. 依赖配置

使用 Apache POI 处理 .xlsx(Excel 2007+)格式时,必须引入 poi-ooxml 依赖:

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

⚠️ 注意:

  • 若需支持旧版 .xls 文件,请改用 poi 依赖
  • 版本建议保持最新稳定版,避免已知 bug

4. 单元格定位

首先加载 Excel 文件并获取工作簿实例:

FileInputStream inputStream = new FileInputStream(new File("SetFormulaTest.xlsx"));
XSSFWorkbook excel = new XSSFWorkbook(inputStream);

接着定位目标单元格。我们的目标是第一行的第一个空列(即 C1):

XSSFSheet sheet = excel.getSheetAt(0);
int lastCellNum = sheet.getRow(0).getLastCellNum(); // 获取最后一列索引
XSSFCell formulaCell = sheet.getRow(0).createCell(lastCellNum + 1); // 创建新单元格

✅ 解释:

  • getLastCellNum() 返回的是“下一个可用列”的索引(从 0 开始)
  • 使用 createCell() 创建新单元格,避免空指针

5. 设置公式与计算

5.1 写入公式

Excel 公式语法可以直接使用,例如:

=SUM(A:A) - SUM(B:B)

在 POI 中通过 setCellFormula() 设置:

formulaCell.setCellFormula("SUM(A:A)-SUM(B:B)");

⚠️ 注意事项:

  • 不要加前导 = 符号,POI 会自动处理
  • 列名使用大写更稳妥(虽然小写通常也能识别)

5.2 触发公式计算

⚠️ 踩坑重点:仅设置公式不会自动计算结果!

Excel 文件保存后打开时才会计算,若希望在程序中立即得到结果,必须手动触发计算引擎:

XSSFFormulaEvaluator formulaEvaluator = excel.getCreationHelper().createFormulaEvaluator();
formulaEvaluator.evaluateFormulaCell(formulaCell);

或者批量评估整个工作表:

formulaEvaluator.evaluateAll();

FormulaEvaluator 提供了多种评估策略:

  • evaluateFormulaCell():评估指定单元格
  • evaluateAll():遍历所有公式单元格并评估
  • 适用于导出前预计算场景

最终效果如下图所示,C1 显示计算结果,公式栏显示原始公式:

Sample Excel File2

6. 总结

本文演示了如何使用 Apache POI 在 Java 中向 Excel 单元格写入公式并主动触发计算。关键点总结如下:

  • ✅ 使用 poi-ooxml 支持 .xlsx 格式
  • ✅ 通过 setCellFormula() 设置公式字符串
  • ❌ 设置公式 ≠ 得到结果,必须调用 FormulaEvaluator
  • ✅ 推荐使用 evaluateAll() 批量处理多个公式

完整示例代码已托管至 GitHub:

https://github.com/eugenp/tutorials/tree/master/apache-poi-2


原始标题:Setting Formulas in Excel with Apache POI