呼叫 excel.Save("D:\\234.xls") 拋出:
System.Runtime.InteropServices.COMException (0x800A03EC):異常來自 HRESULT:0x800A03EC
堆疊追蹤指向 ApplicationClass.SaveWorkspace。
Application.Save() 是儲存工作區(.xlw),非儲存活頁簿(.xls/.xlsx)。Workbook.SaveAs() 或 Workbook.Save()。D:\\234.xls 若資料夾不存在、唯讀、或 Excel 程序無寫入權限,亦會觸發 0x800A03EC。using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
public bool ExportDataGridView(DataGridView gridView, string filePath)
{
if (gridView.Rows.Count == 0)
{
MessageBox.Show("無資料可匯出", "提示");
return false;
}
Excel.Application excel = null;
Excel.Workbook wb = null;
Excel.Worksheet ws = null;
try
{
excel = new Excel.Application();
excel.Visible = false;
excel.DisplayAlerts = false; // 關閉覆蓋確認對話框
wb = excel.Workbooks.Add(Type.Missing);
ws = (Excel.Worksheet)wb.ActiveSheet;
// 寫入標題列
for (int c = 0; c < gridView.Columns.Count; c++)
ws.Cells[1, c + 1] = gridView.Columns[c].HeaderText;
// 寫入資料列(建議用陣列一次寫入,效能佳)
object[,] data = new object[gridView.Rows.Count, gridView.Columns.Count];
for (int r = 0; r < gridView.Rows.Count; r++)
for (int c = 0; c < gridView.Columns.Count; c++)
data[r, c] = gridView.Rows[r].Cells[c].Value?.ToString() ?? "";
Excel.Range rng = ws.Range[ws.Cells[2, 1], ws.Cells[gridView.Rows.Count + 1, gridView.Columns.Count]];
rng.Value2 = data;
// 自動調整欄寬
rng.EntireColumn.AutoFit();
// 確保目錄存在
var dir = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
// 正確儲存:Workbook.SaveAs
wb.SaveAs(filePath, Excel.XlFileFormat.xlWorkbookNormal,
Type.Missing, Type.Missing, false, false,
Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
return true;
}
catch (Exception ex)
{
MessageBox.Show($"匯出失敗:{ex.Message}", "錯誤");
return false;
}
finally
{
// 依序釋放 COM 物件(反向順序)
if (ws != null) Marshal.ReleaseComObject(ws);
if (wb != null) { wb.Close(false); Marshal.ReleaseComObject(wb); }
if (excel != null) { excel.Quit(); Marshal.ReleaseComObject(excel); }
GC.Collect(); GC.WaitForPendingFinalizers(); // 強制回收 RCW
}
}
Workbook.SaveAs 指定格式 xlWorkbookNormal(.xls)或 xlOpenXMLWorkbook(.xlsx)。Range.Value2 = object[,] 比逐格寫入快 100 倍以上。Marshal.ReleaseComObject + GC.Collect(),避免 Excel.exe 残留。ws.Cells["A1"].LoadFromDataTable(dt, true);HSSFWorkbook/XSSFWorkbook。ws.Cell(1,1).Value = "標題";若為伺服器端/容器化部署,強烈建議改用 EPPlus/NPOI/ClosedXML,避免 Office Interop 需安裝 Excel、權限、DCOM 設定等坑。
dcomcnfg → 元件服務 → Microsoft Excel Application → 身分識別 → 互動式使用者。