首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 讀取 Excel 公式計算值:POI vs JExcelAPI 方案對比

     編輯:Java 相關知識

痛點背景

Excel 儲存格可能包含公式(如 =SUM(A1:A10))。Java 讀取時,需獲取公式計算後的結果值,而非公式字串。早期 Apache POI 正式版不支援此功能,開發者常面臨選型困境。

方案一:Apache POI(現代版本已完美支援)

現狀說明

  • POI 3.15+ (2017 年起) 內建 FormulaEvaluator,完整支援公式計算。
  • 早期文檔提及的「開發中功能」已正式釋出,無需第三方擴展。

核心代碼範例


import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;

public class PoiFormulaReader {
    public static void main(String[] args) throws IOException {
        try (FileInputStream fis = new FileInputStream("report.xlsx");
             Workbook wb = new XSSFWorkbook(fis)) {
            
            FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
            Sheet sheet = wb.getSheetAt(0);
            
            for (Row row : sheet) {
                for (Cell cell : row) {
                    CellValue cellValue = evaluator.evaluate(cell);
                    switch (cellValue.getCellType()) {
                        case NUMERIC:
                            System.out.println(cell.getAddress() + " = " + cellValue.getNumberValue());
                            break;
                        case STRING:
                            System.out.println(cell.getAddress() + " = " + cellValue.getStringValue());
                            break;
                        case BOOLEAN:
                            System.out.println(cell.getAddress() + " = " + cellValue.getBooleanValue());
                            break;
                        case ERROR:
                            System.out.println(cell.getAddress() + " = ERROR: " + 
                                FormulaError.forInt(cellValue.getErrorValue()).getString());
                            break;
                        default:
                            System.out.println(cell.getAddress() + " = (空白或不支援型別)");
                    }
                }
            }
        }
    }
}

關鍵類別

  • Workbook.getCreationHelper().createFormulaEvaluator():建立評估器。
  • FormulaEvaluator.evaluate(Cell):計算公式,返回 CellValue(不修改原儲存格)。
  • FormulaEvaluator.evaluateAll():批次計算整個工作簿。
  • FormulaEvaluator.evaluateInCell(Cell):計算並將結果寫回儲存格(修改檔案)。

方案二:JExcelAPI (jxl) - 歷史備選

特性(截至 2.6.12 版)

  • 支援讀寫 Excel 95~2003 (.xls)
  • 支援公式讀寫(僅英文、法文、西班牙文、德文公式)
  • 生成 Excel 2000 格式
  • 支援字型、數字/日期格式、陰影、邊框、圖表、影像複製
  • 國際化支援,整合 Commons Logging / Log4j

代碼範例


import jxl.*;
import jxl.read.biff.BiffException;
import java.io.File;
import java.io.IOException;

public class JxlFormulaReader {
    public static void main(String[] args) throws IOException, BiffException {
        Workbook wb = Workbook.getWorkbook(new File("report.xls"));
        Sheet sheet = wb.getSheet(0);
        
        for (int row = 0; row < sheet.getRows(); row++) {
            for (int col = 0; col < sheet.getColumns(); col++) {
                Cell cell = sheet.getCell(col, row);
                // jxl 直接返回計算後值(若支援該公式)
                System.out.println(cell.getContents());
            }
        }
        wb.close();
    }
}

深度對比:POI vs JExcelAPI

維度Apache POIJExcelAPI (jxl)
檔案格式支援.xls, .xlsx, .xlsm, .xlsb.xls (Excel 95-2003)
公式引擎完整支援 300+ 函數、自訂函數、陣列公式有限函數集,語言限制
效能/記憶體SXSSF 流式寫入支援大檔案全載入記憶體,大檔案易 OOM
維護狀態活躍開發,頻繁釋出停止更新(最後版本 2011 年)
社群/生態龐大,Spring、Hibernate 整合原生極小,文檔稀缺
Maven 坐標org.apache.poi:poi-ooxml:5.3.0net.sourceforge.jexcelapi:jxl:2.6.12

選型建議

  1. 新專案 / .xlsx / 複雜公式 / 大檔案:唯一選擇 Apache POI。
  2. 維護舊系統 / 僅 .xls / 簡單公式:JExcelAPI 仍可運行,但建議規劃遷移 POI。
  3. 唯讀高效能場景:考慮 fastexcel (唯讀、流式、極快) 或 easyexcel (阿里開源、低記憶體)。

進階技巧:POI 公式評估最佳實踐


// 1. 重複使用評估器(執行緒不安全,單執行緒復用)
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

// 2. 強制重新計算所有公式(開啟檔案後首次)
evaluator.evaluateAll();

// 3. 處理外部連結公式(需實作 UDFFinder)
// evaluator.setupReferencedWorkbooks(Map);

// 4. 自訂函數(UDF)
// evaluator.getWorkbook().addToolPack(new MyCustomToolPack());

// 5. 錯誤處理
CellValue cv = evaluator.evaluate(cell);
if (cv.getCellType() == CellType.ERROR) {
    FormulaError err = FormulaError.forInt(cv.getErrorValue());
    // #N/A, #DIV/0!, #VALUE!, #REF!, #NAME?, #NUM!, #NULL!
}

總結

Apache POI 早已解決「讀取公式計算值」難題,且持續進化支援最新 Excel 格式與複雜公式。JExcelAPI 因停止維護、格式受限,已不適合新專案。掌握 POI FormulaEvaluator 核心 API、流式處理 (SXSSF)、錯誤處理與自訂函數擴展,是 Java 處理 Excel 業務的必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved