Contents

Java操作POI修改報表sample檔發生信任活頁簿問題

Apache POI 是 Java 用來操作 Microsoft Office 文件(Word、Excel、PowerPoint)的開源函式庫。在實務開發中,常見的做法是先準備一個 Excel 樣板(sample 檔),再透過程式填入資料後另存新檔。

Apache POI 主要類別

Apache POI 針對 Excel 提供兩種主要 API:

API 格式 說明
HSSF .xls(Excel 97-2003) 處理舊版 Excel 格式
XSSF .xlsx(Excel 2007+) 處理新版 OpenXML 格式

現代專案建議使用 XSSF(XSSFWorkbook),因為 .xlsx 是目前主流格式,支援更多儲存格數量與功能。

信任活頁簿問題的原因

當程式流程如下:

  1. 讀取 Excel SAMPLE 檔案(含有公式計算鏈)
  2. 透過 POI 寫入資料
  3. 另存新檔到 xxxx.xlsx

開啟產生的檔案時,Excel 可能出現「信任活頁簿」警告或自動修復提示。

根本原因.xlsx 是 ZIP 壓縮格式,內部有一個 xl/calcChain.xml 檔案,記錄公式的計算順序。當 POI 修改了儲存格內容但沒有同步更新 calcChain.xml,Excel 開啟時偵測到計算鏈與實際內容不一致,就會發出警告並嘗試自動修復。雖然修復後功能正常,但每次開啟都會彈出提示,影響使用體驗。

解決方法

方法一:從樣板 ZIP 中移除 calcChain.xml(最快)

.xlsx 本質上是 ZIP 壓縮包,可用壓縮軟體(如 7-Zip、WinRAR)開啟 SAMPLE 檔,刪除其中的 xl/calcChain.xml,再儲存。往後 POI 產生的報表就不會有計算鏈衝突。

1
2
# Linux/Mac 可直接用 zip 指令刪除
zip -d sample.xlsx xl/calcChain.xml

方法二:程式中設定強制重新計算

在寫入完成後,呼叫 setForceFormulaRecalculation(true),讓 Excel 開啟時自動重新計算公式,不依賴舊的計算鏈:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;

public class ExcelReport {
    public static void generate(String templatePath, String outputPath) throws IOException {
        try (FileInputStream fis = new FileInputStream(templatePath);
             XSSFWorkbook workbook = new XSSFWorkbook(fis)) {

            // 寫入資料
            var sheet = workbook.getSheetAt(0);
            var row = sheet.getRow(1);
            if (row == null) row = sheet.createRow(1);
            row.createCell(0).setCellValue("報表資料");

            // 強制 Excel 開啟時重新計算公式,避免計算鏈衝突
            workbook.setForceFormulaRecalculation(true);

            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                workbook.write(fos);
            }
        }
    }
}

方法三:使用 XSSFFormulaEvaluator 重新評估

1
2
// 讓 POI 在寫出前先重新評估所有公式
XSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);

建議作法

  • 樣板設計時盡量減少複雜的交叉公式鏈
  • 若樣板只是格式用途(無巨集),直接刪除 xl/calcChain.xml 是最簡單的解法
  • 程式中固定加上 setForceFormulaRecalculation(true),確保任何環境下都相容

參考資料