企業應用中,列印需求千差萬別。若程式內建列印邏輯,維護成本極高。利用幾乎普及的 Excel,將資料匯出至試算表,讓使用者善用 Excel 強大的排版、圖表、篩選、列印功能自行定製,兼顧開發效率與使用者彈性。
.NET 執行環境(CLR)管理記憶體、型別安全,稱為受控代碼。Excel COM 元件屬於非受控代碼。C# 呼叫 Excel 必須透過RCW (Runtime Callable Wrapper) 包裝,將 COM 介面轉為 .NET 型別。Visual Studio 「加入參考」→「COM」→選取 Microsoft Excel XX.0 Object Library 即可自動生成 Interop 組件(命名空間 Microsoft.Office.Interop.Excel)。
var excel = new Excel.Application();
excel.Workbooks.Add(Type.Missing); // 新增空白活頁簿
excel.Visible = true; // 顯示視窗
excel.Cells[1, 1] = "第一欄標題";
excel.Cells[1, 2] = "第二欄標題";
excel.Cells[2, 1] = "資料列1";
excel.Cells[2, 2] = "資料列2";
string connStr = "Provider=msdaora.1;Data Source=MyDB;User ID=usr;Password=pwd;";
using (var cn = new OleDbConnection(connStr))
{
cn.Open();
using (var cmd = new OleDbCommand("SELECT * FROM Schema.Table", cn))
using (var dr = cmd.ExecuteReader())
{
var xlApp = new Excel.Application();
if (xlApp == null) { MessageBox.Show("無法啟動 Excel"); return; }
xlApp.Workbooks.Add(true);
int row = 2, colCount = dr.FieldCount;
// 寫入標題列
for (int c = 0; c < colCount; c++)
xlApp.Cells[1, c + 1] = dr.GetName(c);
// 寫入資料列
while (dr.Read())
{
for (int c = 0; c < colCount; c++)
xlApp.Cells[row, c + 1] = dr.GetValue(c)?.ToString();
row++;
}
xlApp.Visible = true;
}
}
object[,],一次寫入 Range.Value2 = arr,避免頻繁跨程序呼叫Marshal.ReleaseComObject,並呼叫 GC.Collect(),防止 Excel 進程殘留