將資料庫查詢結果匯出為 Excel 報表,支援多工作表分頁(突破 65535 列限制)、自訂雙層表頭、主標題、列印日期,並妥善管理 COM 物件生命週期。
public class ExcelManager : IDisposable
{
// Excel COM 物件
private Excel.Application m_objExcel;
private Excel._Workbook m_objBook;
private Excel.Sheets m_objSheets;
private Excel._Worksheet m_objSheet;
private Excel.Range m_objRange;
private Excel.QueryTable m_objQryTable;
private object m_objOpt = Missing.Value;
// 資料庫相關
private SqlConnection sqlConn;
private double dbSheetSize = 65535; // 單張工作表最大列數
private int intSheetTotalSize; // 總工作表數
private double dbTotalSize; // 總筆數
// 建構子多載:支援傳入連線、指定分頁大小、自動計算分頁數
public ExcelManager() { }
public ExcelManager(double sheetSize, double total, int sheets, SqlConnection conn) { ... }
public ExcelManager(double sheetSize, string tableName, SqlConnection conn) { ... }
// IDisposable 標準實作,確保釋放 COM 物件
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
private void Dispose(bool disposing) { ... }
// 取得資料表總筆數並計算分頁數
private int GetTotalSize(string tableName, SqlConnection conn) { ... }
// 核心匯出流程
public void DeclareExcelApp(string[] titles, string sqlFields, string tableName, string mainTitle) { ... }
// 另存新檔對話框
public void SaveExcelApp() { ... }
// 使用 QueryTable 高效匯出資料到指定工作表
private void ExportDataByQueryTable(int sheetNo, bool isContinuation, string[] titles, string sql, string table, string mainTitle) { ... }
}
TOP N 與 NOT IN (SELECT TOP M ...) 實作分頁查詢,自動建立多張工作表。Dispose 中呼叫 Marshal.FinalReleaseComObject 逐層釋放,避免 Excel 残留進程。var connStr = "Data Source=localhost;User ID=sa;Password=;Initial Catalog=Northwind";
using (var conn = new SqlConnection(connStr))
using (var excel = new ExcelManager(65530, "Orders", conn))
{
try
{
excel.DeclareExcelApp(
new[] { "訂單編號", "客戶編號" },
" OrderID, CustomerID ",
"Orders",
"北風貿易訂單報表"
);
// excel.SaveExcelApp(); // 可選:另存新檔
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}