| 對象 | 角色 | 關鍵方法/屬性 |
| ReleaseManager | COM 容器管理器 | release() 釋放所有資源 |
| IDispatch | 通用 COM 物件包裝 | get(name)/put(name,val)/method(name,args[]) |
完整操作流程(含代碼片段)
1. 識別文件類型並創建 Excel 應用對象
if (path.endsWith(".xls")) {
ReleaseManager rm = new ReleaseManager();
IDispatch xlsApp = new IDispatch(rm, "Excel.Application");
xlsApp.put("Visible", new Boolean(false)); // 後台運行
}
2. 打開工作簿
IDispatch workbooks = (IDispatch) xlsApp.get("Workbooks");
IDispatch workbook = (IDispatch) workbooks.method("Open", new Object[]{ filePath });
3. 另存為(如轉 CSV/HTML)
// FileFormat: 9=Excel 97-2003, 6=CSV, 44=HTML
workbook.method("SaveAs", new Object[]{ outPath, new Integer(9) });
4. 遍歷工作表
IDispatch sheets = (IDispatch) workbook.get("Sheets");
int count = Integer.parseInt(sheets.get("Count").toString());
for (int i = 1; i <= count; i++) { // COM 索引從 1 開始
IDispatch sheet = (IDispatch) sheets.get("Item", new Object[]{ new Integer(i) });
String name = sheet.get("Name").toString();
// 或按名獲取:sheets.get("Item", new Object[]{ name })
}
5. 獲取行列數(兩種模式)
// 全部行列(含空白)
int rows = Integer.parseInt(((IDispatch)sheet.get("Rows")).get("Count").toString());
int cols = Integer.parseInt(((IDispatch)sheet.get("Columns")).get("Count").toString());
// 僅已用區域
IDispatch used = (IDispatch) sheet.get("UsedRange");
int usedRows = Integer.parseInt(((IDispatch)used.get("Rows")).get("Count").toString());
int usedCols = Integer.parseInt(((IDispatch)used.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(); // 數值型返回 "1.0"
String txt = cell.get("Text").toString(); // 顯示文本
String hasF = cell.get("HasFormula").toString(); // true/false
String fml = cell.get("FormulaR1C1").toString(); // 公式內容
}
}
7. 工作表保護/解除保護
// 保護
sheet.method("Protect", new Object[]{ password, Boolean.TRUE, Boolean.TRUE });
// 解除
sheet.method("Unprotect", new Object[]{ password });
8. 必須的資源釋放(放在 finally)
try {
// ... 業務邏輯
} finally {
if (xlsApp != null) {
((IDispatch)xlsApp.get("ActiveWorkbook")).put("Saved", Boolean.TRUE);
xlsApp.method("Quit", null);
xlsApp = null;
}
if (rm != null) { rm.release(); rm = null; }
// 若單獨關閉 workbook
// workbook.method("Close", null);
}
警告:漏掉 rm.release() 會導致 EXCEL.EXE 殭屍進程殘留!
JCOM vs Apache POI 選型建議
| 維度 | JCOM | Apache POI |
| 依賴 | 需安裝 Excel、Windows 平台 | 純 Java、跨平台 |
| 功能完整度 | 100% Excel 功能(含宏、圖表、樞紐) | 核心功能全,高級功能有限 |
| 性能 | 進程間通訊開銷大,慢 | 記憶體內操作,快 |
| 併發 | 單進程 Excel 實例,難併發 | 線程安全,適合服務端 |
| 適用場景 | 客戶端工具、複雜報表自動化、宏觸發 | 服務端導入導出、批量處理 |
結語
JCOM 是「借用 Excel 引擎」的捷徑,適合必須依賴 Excel 完整計算/渲染/宏能力的客戶端場景。服務端批量處理請毫猶豫選 POI。掌握 ReleaseManager 生命周期管理、COM 索引從 1 開始、四種單元格屬性區別,是用好 JCOM 的關鍵。
- 上一篇文章: J2ME 開發中文模擬器選型指南:Nokia 系列完美支援
- 下一篇文章: Java 計算任意兩日期間工作日數:無節假日版演算法實現
Copyright ©
程式碼之家 All Rights Reserved