Excel 作為企業最常用的資料工具,C# 操作 Excel 的需求極高。本文介紹兩種主流做法:OleDb 資料存取(適合大量資料讀寫、無需安裝 Excel)與 COM 自動化(完整控制 Excel 應用程式、支援格式、圖表、巨集)。
.xls (Excel 97-2003):
Provider=Microsoft.Jet.OLEDB.4.0;Data Source={path};Extended Properties="Excel 8.0;HDR=YES;IMEX=1"
.xlsx (Excel 2007+):
Provider=Microsoft.ACE.OLEDB.12.0;Data Source={path};Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1"
關鍵參數:HDR=YES 第一列為標題,IMEX=1 混合資料型別當文字處理。
using System;
using System.Data;
using System.Data.OleDb;
using System.Windows.Forms;
public class ExcelOleDbReader
{
public static DataTable ReadExcelSheet(string filePath, string sheetName = "Sheet1")
{
string connStr = $"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={filePath};Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\"";
using var conn = new OleDbConnection(connStr);
string query = $"SELECT * FROM [{sheetName}$]";
using var adapter = new OleDbDataAdapter(query, conn);
var dt = new DataTable();
adapter.Fill(dt);
return dt;
}
}
// 使用範例
public class ExcelViewerForm : Form
{
private DataGridView _grid;
private Button _btnLoad;
public ExcelViewerForm()
{
_grid = new DataGridView { Dock = DockStyle.Fill, ReadOnly = true, AllowUserToAddRows = false };
_btnLoad = new Button { Text = "載入 Excel", Dock = DockStyle.Bottom, Height = 40 };
_btnLoad.Click += async (s, e) => {
using var dlg = new OpenFileDialog { Filter = "Excel Files|*.xls;*.xlsx" };
if (dlg.ShowDialog() == DialogResult.OK)
{
try
{
var dt = ExcelOleDbReader.ReadExcelSheet(dlg.FileName);
_grid.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show($"讀取失敗:{ex.Message}");
}
}
};
this.Controls.AddRange(new Control[] { _grid, _btnLoad });
this.Text = "Excel OleDb 讀取器";
this.ClientSize = new Size(800, 600);
}
}

圖 01:OleDb 讀取 Excel 並繫結 DataGridView
OleDb 不支援建立新活頁簿,僅能對現有檔案的工作表進行 INSERT/UPDATE。建立新檔案請改用 COM 或開源庫(EPPlus, ClosedXML, NPOI)。
右鍵專案 → 加入參考 → COM → 搜尋 "Microsoft Excel 16.0 Object Library" (版本依安裝 Office 而定)。
using Excel = Microsoft.Office.Interop.Excel;
public class ExcelAutomation
{
public void CreateAndWriteReport(string filePath)
{
Excel.Application excelApp = null;
Excel.Workbook wb = null;
Excel.Worksheet ws = null;
try
{
excelApp = new Excel.Application();
excelApp.Visible = false; // 背景執行
excelApp.DisplayAlerts = false;
wb = excelApp.Workbooks.Add();
ws = (Excel.Worksheet)wb.ActiveSheet;
ws.Name = "報表";
// 寫入標題
ws.Cells[1, 1] = "編號";
ws.Cells[1, 2] = "品名";
ws.Cells[1, 3] = "金額";
// 寫入資料
var data = new[] {
new { Id = 1, Name = "筆記型電腦", Price = 35000 },
new { Id = 2, Name = "滑鼠", Price = 500 },
new { Id = 3, Name = "螢幕", Price = 8000 }
};
for (int i = 0; i < data.Length; i++)
{
ws.Cells[i + 2, 1] = data[i].Id;
ws.Cells[i + 2, 2] = data[i].Name;
ws.Cells[i + 2, 3] = data[i].Price;
}
// 設定欄寬與格式
ws.Columns.AutoFit();
Excel.Range priceRange = ws.Range["C2", $"C{data.Length + 1}"];
priceRange.NumberFormat = "#,##0";
wb.SaveAs(filePath);
}
finally
{
// 正確釋放 COM 物件(極重要!)
ReleaseComObject(ws);
ReleaseComObject(wb);
if (excelApp != null)
{
excelApp.Quit();
ReleaseComObject(excelApp);
}
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
private void ReleaseComObject(object obj)
{
if (obj != null && System.Runtime.InteropServices.Marshal.IsComObject(obj))
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
}
}
}

圖 02:COM 自動化建立格式化 Excel 報表
public DataTable ReadWithCom(string filePath, string sheetName)
{
Excel.Application app = new Excel.Application();
Excel.Workbook wb = app.Workbooks.Open(filePath);
Excel.Worksheet ws = wb.Sheets[sheetName];
Excel.Range used = ws.UsedRange;
object[,] values = (object[,])used.Value2;
var dt = new DataTable();
// 假設第一列為標題
for (int c = 1; c <= used.Columns.Count; c++)
dt.Columns.Add(values[1, c]?.ToString() ?? $"Col{c}");
for (int r = 2; r <= used.Rows.Count; r++)
{
var row = dt.NewRow();
for (int c = 1; c <= used.Columns.Count; c++)
row[c - 1] = values[r, c]?.ToString() ?? "";
dt.Rows.Add(row);
}
wb.Close(false);
app.Quit();
ReleaseComObject(used); ReleaseComObject(ws); ReleaseComObject(wb); ReleaseComObject(app);
return dt;
}
| 特性 | OleDb | COM 自動化 |
|---|---|---|
| 需安裝 Excel | 否 (需 ACE 驅動) | 是 |
| 效能 (大量資料) | 極快 | 較慢 (進程間通訊) |
| 格式/樣式控制 | 無 | 完整支援 |
| 圖表/樞紐分析表 | 不支援 | 支援 |
| 伺服器端部署 | 適合 | 不建議 (需互動式登入) |
| 建立新檔案 | 不支援 | 支援 |
無需安裝 Office、跨平台、效能優異:
// ClosedXML 範例
using ClosedXML.Excel;
var wb = new XLWorkbook();
var ws = wb.AddWorksheet("報表");
ws.Cell(1, 1).Value = "Hello ClosedXML";
wb.SaveAs("Demo.xlsx");
讀取大量資料首選 OleDb 或 ClosedXML;需複雜格式、圖表、巨集互動才使用 COM 自動化,並務必正確釋放 COM 物件避免殘留 Excel 進程。現代專案建議優先評估純 .NET 函式庫,提升部署彈性與效能。