#define OFFICE_VER 11 // Office XP (10=2000, 11=XP, 12=2003...)
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\MSO.DLL" \
rename("RGB", "MSRGB") rename("DocumentProperties", "MSDocumentProperties")
#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\EXCEL.EXE" \
rename("DialogBox", "MSDialogBox") rename("RGB", "MSRGB") \
rename("CopyFile", "MSCopyFile") rename("ReplaceText", "MSReplaceText") \
no_dual_interfaces
using namespace Excel;
rename 避免名稱衝突,no_dual_interfaces 強制使用早期繫結介面提升效能。
CoInitialize(NULL);
// ... 程式碼 ...
CoUninitialize();
_ApplicationPtr - Excel 應用程式WorkbooksPtr - 工作簿集合_WorkbookPtr - 單一工作簿 (.xls)SheetsPtr / WorksheetsPtr - 工作表集合_WorksheetPtr - 單一工作表RangePtr - 儲存格區域集合_ApplicationPtr pApp;
HRESULT hr = pApp.CreateInstance(__uuidof(Application));
if (FAILED(hr)) return;
pApp->Visible = VARIANT_TRUE; // 顯示視窗
// 新增空白工作簿
WorkbooksPtr pBooks = pApp->Workbooks;
_WorkbookPtr pBook = pBooks->Add((long)xlWorkbookDefault);
// 或開啟現有檔案
_WorkbookPtr pBook = pBooks->Open(_T("C:\\Data\\Report.xls"),
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
vtMissing, vtMissing, vtMissing, vtMissing);
SheetsPtr pSheets = pBook->Worksheets;
// 取得第一張工作表
_WorksheetPtr pSheet = pSheets->Item[1]; // 索引從 1 開始
// 或取得作用中工作表
_WorksheetPtr pSheet = pBook->ActiveSheet;
// 重新命名
pSheet->Name = _T("銷售報表");
// 新增工作表
_WorksheetPtr pNewSheet = pSheets->Add(vtMissing, vtMissing, 1, xlWorksheet);
// 寫入單一儲存格
RangePtr pRange = pSheet->Range[_T("A1")];
pRange->Value2 = _T("產品名稱");
pRange->Font->Bold = VARIANT_TRUE;
pRange->Font->Size = 14;
pRange->Font->Name = _T("微軟正黑體");
pRange->Interior->Color = RGB(255, 255, 0); // 黃底
// 批次寫入陣列資料 (高效)
long rows = 100, cols = 5;
SAFEARRAYBOUND sab[2] = {{rows, 1}, {cols, 1}};
SAFEARRAY* psa = SafeArrayCreate(VT_VARIANT, 2, sab);
// 填充 psa...
RangePtr pBlock = pSheet->Range[_T("A2"), _T("E101")];
pBlock->Value2 = psa;
SafeArrayDestroy(psa);
pBook->SaveAs(_T("C:\\Output\\Report.xls"),
xlWorkbookNormal, vtMissing, vtMissing, vtMissing, vtMissing,
xlNoChange, vtMissing, vtMissing, vtMissing, vtMissing);
pBook->Close(VARIANT_FALSE, vtMissing, vtMissing);
pApp->Quit();
_ApplicationPtr 等智慧指標自動管理 AddRef/Release,離開作用域自動釋放。pSheet->Name = _T("New") 等同 pSheet->put_Name(_T("New"));pRange->Value2 直接讀寫。-> 無智慧提示時,先用 . 查看成員,再改回 ->。HRESULT,配合 _com_error 例外機制:try {
pRange->Value2 = _T("Test");
} catch (_com_error& e) {
CString msg; msg.Format(_T("Excel 錯誤: %s (0x%08X)"), e.ErrorMessage(), e.Error());
AfxMessageBox(msg);
}
| 問題 | 解決方案 |
|---|---|
| Excel 進程殘留 | 確保所有智慧指標離開作用域,呼叫 Quit(),必要時 CoUninitialize |
| 中文亂碼 | 使用 _bstr_t 或 _T() 宏,確保 Unicode 建置 |
| 儲存格公式不計算 | 設定 pApp->Calculation = xlCalculationAutomatic |
| 效能差 | 批次陣列寫入、關閉螢幕更新 pApp->ScreenUpdating = VARIANT_FALSE |
#import + 智慧指標是 VC++ 自動化 Excel 的現代最佳實踐:型別安全、記憶體自管、語法接近 VBA。掌握物件層級、SAFEARRAY 批次資料、屬性存取語法糖與錯誤處理,即可高效開發專業級 Excel 報表自動化系統。