應用程式中以 StringGrid 控制元件顯示資料庫查詢結果,需依相同行列格式匯出至 Excel 檔案(.xls)。本文提供兩種成熟方案,分別適用於不同效能與靈活度需求。
透過 COM 自動化逐一寫入每個儲存格,適合資料量較小、需精細控制格式的場景。
Variant ExcelApp, WorkBook1, WorkSheet1;
AnsiString FileName = ExtractFileDir(Application->ExeName) + "\\a.xls";
try {
ExcelApp = Variant::CreateObject("Excel.Application");
} catch(...) {
ShowMessage("Sorry! Excel cannot be launched");
return;
}
ExcelApp.OlePropertySet("Visible", true);
ExcelApp.OlePropertyGet("WorkBooks").OleProcedure("Open", FileName.c_str());
WorkBook1 = ExcelApp.OlePropertyGet("ActiveWorkBook");
WorkSheet1 = WorkBook1.OlePropertyGet("ActiveSheet");
for (int i = 0; i < StringGrid1->RowCount; i++) {
for (int j = 0; j < StringGrid1->ColCount; j++) {
WorkSheet1.OlePropertyGet("Cells", i+1, j+1)
.OlePropertySet("Value", StringGrid1->Cells[j][i].c_str());
}
}
ExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", FileName.c_str());
ExcelApp.OleFunction("Quit");
WorkSheet1 = Unassigned;
WorkBook1 = Unassigned;
ExcelApp = Unassigned;
優點:直觀易懂,可對單一儲存格設定格式、公式等。
缺點:大量資料時效能極差(每次跨程序 COM 呼叫開銷大)。
利用 Excel 的 QueryTables 功能,直接將 ADO Recordset 批量導入工作表,效能大幅提升。
Variant ExcelApp, WorkBook1, Sheet1, Range, Table, QueryTables;
int Count;
AnsiString ITemp, IStr, sSQL;
try {
ExcelApp = CreateOleObject("Excel.Application");
} catch(...) {
ShowMessage("請確認已安裝 Excel");
return;
}
ExcelApp.OlePropertyGet("WorkBooks").OleFunction("Add");
WorkBook1 = ExcelApp.OlePropertyGet("ActiveWorkBook");
Sheet1 = WorkBook1.OlePropertyGet("ActiveSheet");
WorkBook1.OlePropertyGet("Sheets", 1).OleProcedure("Select");
Sheet1.OlePropertySet("name", "報表");
// 設定資料來源為 ADO Recordset
QueryTables = Sheet1.OlePropertyGet("QueryTables");
sSQL = "SELECT * FROM Table"; // 實際 SQL
qryTmp->Active = false;
qryTmp->SQL->Clear();
qryTmp->SQL->Add(sSQL);
qryTmp->Active = true;
Count = qryTmp->RecordCount + 12; // 含標題列偏移
IStr = "A9:M" + IntToStr(Count);
Range = Sheet1.OlePropertyGet("Range", "A9");
Table = QueryTables.OleFunction("Add", qryTmp->Recordset, Range);
Table.OlePropertySet("FieldNames", false);
// 自動調整欄寬並刷新資料
Range = Sheet1.OlePropertyGet("Range", IStr.c_str());
Sheet1.OlePropertyGet("Range", "A:K").OlePropertyGet("Columns").OleProcedure("AutoFit");
Table.OleProcedure("Refresh", true);
WorkBook1.OleFunction("SaveAs", "E:\\6.xls");
ShowMessage("導出完畢,請檢查");
qryTmp->Active = false;
ExcelApp.OleFunction("Quit");
ExcelApp = Unassigned;
優點:速度極快(批量傳輸),適合大數據量。
缺點:對單一儲存格格式控制較弱,需依賴 Excel 版本支援 QueryTables。
| 場景 | 推薦方案 |
|---|---|
| 資料 < 500 行、需複雜格式/公式 | 方案一 |
| 資料 > 1000 行、純資料匯出 | 方案二 |
| 需支援無 Excel 環境 | 考慮第三方庫(如 libxl、OpenXLSX) |
Unassigned,避免記憶體洩漏。Visible = false)提升速度。