jdom-1.0.jarjxl-2.5.5.jar (純 Java 讀寫 Excel)jcom-2.2.4.jar (Java-COM 橋接)jcom.dll **必須放入 JDK bin 目錄或系統 System32** (推薦 JDK 目錄,避免污染系統)ReleaseManager rm = new ReleaseManager(); // COM 組件容器,管理生命週期
IDispatch xlsApp = new IDispatch(rm, "Excel.Application"); // Excel Application 對象
// 所有 COM 對象均表現為 IDispatch,操作均拋出 JComException
IDispatch workbooks = (IDispatch) xlsApp.get("Workbooks");
xlsApp.put("Visible", new Boolean(false)); // 後台運行
IDispatch workbook = (IDispatch) workbooks.method("open", new Object[]{ filePath });
File f = new File(outPath);
if (f.exists()) f.delete();
workbook.method("saveAs", new Object[]{ outPath, new Integer(9) });
IDispatch sheets = (IDispatch) workbook.get("Sheets");
int count = Integer.parseInt(sheets.get("Count").toString());
// ⚠️ Excel 索引從 1 開始!
for (int i = 1; i <= count; i++) {
IDispatch sheet = (IDispatch) sheets.get("Item", new Object[]{ new Integer(i) });
// 或按名稱:sheets.get("Item", new Object[]{ sheetName })
String name = sheet.get("Name").toString();
}
| 類型 | 代碼 | 說明 |
|---|---|---|
| 總行數 (65536) | sheet.get("Rows").get("Count") | 含空行 |
| 總列數 (256) | sheet.get("Columns").get("Count") | 含空列 |
| 已用區域行數 | sheet.get("UsedRange").get("Rows").get("Count") | 實際數據範圍 |
| 已用區域列數 | sheet.get("UsedRange").get("Columns").get("Count") | 實際數據範圍 |
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= cols; c++) {
IDispatch cell = (IDispatch) sheet.get("Cells", new Object[]{ new Integer(r), new Integer(c) });
String val = cell.get("Value").toString(); // 數值型會帶 .0 (如 1 → "1.0")
String txt = cell.get("Text").toString(); // 顯示文本原樣
boolean hasF = Boolean.parseBoolean(cell.get("HasFormula").toString());
String formula = cell.get("FormulaR1C1").toString(); // R1C1 風格公式
}
}
IDispatch activeSheet = (IDispatch) xlsApp.get("ActiveSheet");
// 保護:密碼、保護繪圖對象、保護內容
activeSheet.method("Protect", new Object[]{ pwd, Boolean.TRUE, Boolean.TRUE });
// 解除
activeSheet.method("Unprotect", new Object[]{ pwd });
**必須在 finally 塊中按逆序釋放,且不可省略 ReleaseManager.release()**
finally {
try {
if (workbook != null) {
workbook.method("close", new Object[]{ Boolean.FALSE }); // 不保存關閉
workbook = null;
}
if (xlsApp != null) {
xlsApp.put("Saved", Boolean.TRUE); // 標記已存,避免彈窗
xlsApp.method("quit", null); // 退出 Excel 進程
xlsApp = null;
}
} finally {
if (rm != null) {
rm.release(); // 釋放底層 COM 資源,關鍵!
rm = null;
}
}
}
workbook.close() 僅關閉工作簿;xlsApp.quit() 才退出 Excel.exe 進程。rm.release() 會導致 EXCEL.EXE 殘留進程,佔用內存並鎖定文件。finally 確保即使 COM 調用拋異常也能釋放資源。JXL (jxl.jar) 無需 COM、無需 Excel 安裝、跨平台、性能較好,但**不支持 .xlsx (Excel 2007+)**、不支持圖表/宏/樞紐表、樣式控制弱。JCOM 適合需完整 Excel 功能、Windows 環境、可接受進程開銷的場景。現代項目推薦 Apache POI (支持 .xls/.xlsx、功能全、純 Java)。