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

Java 整合 JCOM 實現 Excel 自動化操作完整指南

     編輯:Java 相關知識

前言

在 Java 開發中,若需實現類似 Excel 的編程操作(如讀寫儲存格、設定公式、保護工作表等),透過 JCOM (Java-COM Bridge) 呼叫 Microsoft Excel 的 COM 介面是一種經典且強大的方案。本文將系統整理 JCOM 搭配 JXL 使用的關鍵步驟、核心 API 呼叫流程與資源釋放最佳實踐,助你快速構建穩健的 Excel 自動化工具類。

一、環境準備與依賴配置

專案啟動前,請確認以下檔案已就緒:

  • JAR 套件:jdom-1.0.jar、jxl-2.5.5.jar、jcom-2.2.4.jar,放置於專案 lib 目錄。
  • 原生庫:jcom.dll 必須置於 JDK/bin 目錄(推薦)或系統 Windows 目錄,否則執行期會拋出 UnsatisfiedLinkError。
所有 JCOM 回傳物件皆為 IDispatch 型別,操作過程需捕獲 JComException。

二、核心物件初始化流程

1. 判斷檔案類型

if (path.endsWith(".xls")) { /* Excel 97-2003 */ }
else if (path.endsWith(".xlsx")) { /* Excel 2007+,需改用 Apache POI */ }

2. 建立 ReleaseManager 與 Excel Application 物件

ReleaseManager rm = new ReleaseManager();
IDispatch xlsApp = new IDispatch(rm, "Excel.Application");
  • ReleaseManager:管理所有 COM 元件生命週期的容器,負責最終資源釋放。
  • IDispatch:COM 物件的通用代理,所有 Excel 物件(Application、Workbook、Worksheet、Range 等)皆以此型別呈現。

3. 取得 Workbooks 集合並設定可見性

IDispatch workbooks = (IDispatch) xlsApp.get("Workbooks");
xlsApp.put("Visible", new Java.lang.Boolean(false)); // 背景執行,不彈出視窗

4. 開啟/建立工作簿

IDispatch workbook = (IDispatch) workbooks.method("Open", new Object[]{ filePath });

5. 另存為指定格式

File outFile = new File(outPath);
if (outFile.exists()) outFile.delete();
workbook.method("SaveAs", new Object[]{ outPath, new Integer(9) }); // 9 = xlWorkbookNormal (.xls)

三、工作表與資料操作詳解

1. 取得所有工作表與計數

IDispatch sheets = (IDispatch) workbook.get("Sheets");
int sheetCount = Integer.parseInt(sheets.get("Count").toString());

2. 遍歷工作表(索引從 1 開始)

for (int i = 1; i <= sheetCount; i++) {
    IDispatch sheet = (IDispatch) sheets.get("Item", new Object[]{ new Integer(i) });
    String name = sheet.get("Name").toString();
    // 或直接用名稱取得:sheets.get("Item", new Object[]{ sheetName })
}

3. 取得作用中工作表

IDispatch activeSheet = (IDispatch) xlsApp.get("ActiveSheet");

4. 取得列/行總數(含隱藏)

int totalRows = Integer.parseInt(((IDispatch)sheet.get("Rows")).get("Count").toString());   // 65536 (Excel 2003)
int totalCols = Integer.parseInt(((IDispatch)sheet.get("Columns")).get("Count").toString()); // 256

5. 取得已使用區域列/行數(效能較佳)

IDispatch usedRange = (IDispatch) sheet.get("UsedRange");
int usedRows = Integer.parseInt(((IDispatch)usedRange.get("Rows")).get("Count").toString());
int usedCols = Integer.parseInt(((IDispatch)usedRange.get("Columns")).get("Count").toString());

6. 讀取儲存格值、文字、公式

for (int r = 1; r <= usedRows; r++) {
    for (int c = 1; c <= usedCols; c++) {
        IDispatch cell = (IDispatch) sheet.get("Cells", new Object[]{ new Integer(r), new Integer(c) });
        String val  = cell.get("Value").toString();      // 數值會帶 .0 (如 1.0)
        String txt  = cell.get("Text").toString();       // 顯示文字
        boolean hasF = Boolean.parseBoolean(cell.get("HasFormula").toString());
        String formula = cell.get("FormulaR1C1").toString(); // R1C1 參考風格公式
    }
}
注意:Excel COM 索引皆從 1 起算;Value 回傳 Double 字串,若需原始顯示請用 Text。

7. 工作表保護與解除保護

// 保護:密碼、保護繪圖物件、保護內容
activeSheet.method("Protect", new Object[]{ password, true, true });
// 解除保護
activeSheet.method("Unprotect", new Object[]{ password });

四、資源釋放與進程清理(關鍵)

若未正確釋放,EXCEL.EXE 將殘留於作業系統進程中。請務必在 finally 區塊執行:

try {
    // ... 業務邏輯
} finally {
    if (xlsApp != null) {
        // 標記已儲存,避免彈出「是否儲存」對話框阻塞進程
        IDispatch activeWb = (IDispatch) xlsApp.get("ActiveWorkbook");
        if (activeWb != null) activeWb.put("Saved", Boolean.TRUE);

        xlsApp.method("Quit", null); // 關閉整個 Excel 應用程式
        xlsApp = null;
    }
    // 釋放所有 COM 參考計數器
    if (rm != null) {
        rm.release();
        rm = null;
    }
    // 建議輔助 GC
    System.gc();
}

補充:關閉單一 Workbook vs 整個 Application

  • workbook.method("Close", null):僅關閉該工作簿,Excel 進程仍在。
  • xlsApp.method("Quit", null):退出 Excel 應用程式,進程結束。

五、常見坑點與最佳實踐總結

  1. 索引從 1 開始:Worksheets、Rows、Columns、Cells 皆同。
  2. Value vs Text:數值運算用 Value,顯示/匯出用 Text。
  3. 公式讀取:FormulaR1C1 回傳 R1C1 風格,若需 A1 風格請用 Formula。
  4. 必須釋放 ReleaseManager:否則 COM 參考計數不歸零,進程常駐。
  5. 多執行緒慎用:Excel COM 為單執行緒套房 (STA),並發呼叫易導致死鎖或資料損毀;建議序列化處理或改用 Apache POI 純 Java 方案。
  6. 大量資料效能:逐儲存格讀寫極慢,建議以陣列 Range.Value = Object[][] 批次讀寫。

結語

JCOM 橋接 Java 與 Excel COM 介面,雖能發揮 Excel 完整功能(公式計算、圖表、列印、VBA 互動等),但部署依賴 Windows 環境與 Excel 安裝,且效能與穩定性受限於進程間通訊。現代專案若無「必須呼叫 Excel 內建引擎」的剛性需求,推薦改用 Apache POI(支援 .xls/.xlsx、純 Java、跨平台、效能優異)。若維護舊系統或需特殊 COM 功能,本文提供的資源管理模式可確保進程乾淨退出,避免伺服器記憶體洩漏。

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