提供兩個即拿即用的函式:ListView2Word、ListView2Excel,將 TListView 內容(含欄標、子項目)完整匯出為 Word 文件或 Excel 試算表,支援欄寬保留、標題列樣式、字體同步。
Variant::CreateObject("Word.Application") / "Excel.Application" 啟動應用程式OlePropertyGet/Set、OleFunction/Procedure 操作物件模型Visible = false),背景完成後自動儲存關閉void __fastcall ListView2Word(TListView* lv, String strDocFile) {
Variant vWordApp, vTable, vCell;
try {
vWordApp = Variant::CreateObject("Word.Application");
} catch (...) {
MessageBox(0, "啟動 Word 失敗,請確認已安裝。", "ListView2Doc", MB_OK|MB_ICONERROR);
return;
}
vWordApp.OlePropertySet("Visible", false);
vWordApp.OlePropertyGet("Documents").OleFunction("Add");
Variant vSelect = vWordApp.OlePropertyGet("Selection");
vSelect.OlePropertyGet("Font").OlePropertySet("Size", lv->Font->Size);
vSelect.OlePropertyGet("Font").OlePropertySet("Name", lv->Font->Name.c_str());
int nRowCount = lv->Items->Count + 1; // +1 標題列
nRowCount = nRowCount < 2 ? 2 : nRowCount;
int nColCount = lv->Columns->Count;
nColCount = nColCount < 1 ? 1 : nColCount;
// 插入表格
vWordApp.OlePropertyGet("ActiveDocument").OlePropertyGet("Tables")
.OleProcedure("Add", vSelect.OlePropertyGet("Range"), nRowCount, nColCount, 1, 0);
vTable = vWordApp.OlePropertyGet("ActiveDocument")
.OleFunction("Range").OlePropertyGet("Tables").OleFunction("Item", 1);
// 設定欄寬(Word 以 Points 為單位,約 1 px = 2 pt)
for (int i = 0; i < nColCount; ++i) {
int w = (i < lv->Columns->Count) ? lv->Columns->Items[i]->Width : 100;
vTable.OlePropertyGet("Columns").OleFunction("Item", i+1)
.OlePropertySet("PreferredWidthType", 3); // wdPreferredWidthPoints
vTable.OlePropertyGet("Columns").OleFunction("Item", i+1)
.OlePropertySet("PreferredWidth", w * 2);
}
// 寫入欄標
for (int i = 0; i < lv->Columns->Count; ++i) {
vCell = vTable.OleFunction("Cell", 1, i+1);
vCell.OlePropertySet("Range", lv->Columns->Items[i]->Caption.c_str());
vCell.OlePropertyGet("Shading")
.OlePropertySet("BackgroundPatternColor", 14737632); // 灰底
}
// 寫入資料
for (int i = 0; i < nRowCount - 1; ++i) {
vCell = vTable.OleFunction("Cell", i+2, 1);
vCell.OlePropertySet("Range", lv->Items->Item[i]->Caption.c_str());
for (int j = 0; j < lv->Items->Item[i]->SubItems->Count; ++j) {
if (lv->Columns->Count > j) {
vCell = vTable.OleFunction("Cell", i+2, j+2);
vCell.OlePropertySet("Range",
lv->Items->Item[i]->SubItems->Strings[j].c_str());
}
}
}
// 儲存並結束
vWordApp.OlePropertyGet("ActiveDocument").OleProcedure("SaveAs", strDocFile.c_str());
vWordApp.OlePropertyGet("ActiveDocument").OleProcedure("Close");
Application->ProcessMessages();
vWordApp.OleProcedure("Quit");
Application->ProcessMessages();
vWordApp = Unassigned;
MessageBox(0, "ListView2Doc 轉換完成!", "ListView2Doc", MB_OK|MB_ICONINFORMATION);
}
void __fastcall ListView2Excel(TListView* lv, String strXlsFile) {
Variant vExcelApp, vSheet;
try {
vExcelApp = Variant::CreateObject("Excel.Application");
} catch (...) {
MessageBox(0, "啟動 Excel 失敗,請確認已安裝。", "ListView2Excel", MB_OK|MB_ICONERROR);
return;
}
vExcelApp.OlePropertySet("Visible", false); // 背景執行
vExcelApp.OlePropertyGet("Workbooks").OleFunction("Add", 1);
vSheet = vExcelApp.OlePropertyGet("ActiveWorkbook").OlePropertyGet("Sheets", 1);
// 字體同步
vSheet.OleProcedure("Select");
vSheet.OlePropertyGet("Cells").OleProcedure("Select");
vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font")
.OlePropertySet("Size", lv->Font->Size);
vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font")
.OlePropertySet("Name", lv->Font->Name.c_str());
vExcelApp.OlePropertyGet("Selection").OlePropertyGet("Font")
.OlePropertySet("FontStyle", "常規");
vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select");
int nRowCount = lv->Items->Count + 1;
nRowCount = nRowCount < 2 ? 2 : nRowCount;
int nColCount = lv->Columns->Count;
nColCount = nColCount < 1 ? 1 : nColCount;
// 欄寬(Excel 寬度單位約 1 px = 1/2.6)
for (int i = 0; i < nColCount; ++i) {
int w = (i < lv->Columns->Count) ? lv->Columns->Items[i]->Width : 100;
vExcelApp.OlePropertyGet("Columns", i+1)
.OlePropertySet("ColumnWidth", w / 2.6);
}
// 寫入欄標(灰底)
for (int j = 0; j < lv->Columns->Count; ++j) {
vExcelApp.OlePropertyGet("Rows", 1).OlePropertySet("RowHeight", 20);
vSheet.OlePropertyGet("Cells", 1, j+1)
.OlePropertySet("Value", lv->Columns->Items[j]->Caption.c_str());
Variant vInter = vSheet.OlePropertyGet("Cells", 1, j+1).OlePropertyGet("Interior");
vInter.OlePropertySet("ColorIndex", 15);
vInter.OlePropertySet("Pattern", 1); // xlSolid
vInter.OlePropertySet("PatternColorIndex", -4105); // xlAutomatic
}
// 寫入資料
for (int i = 0; i < nRowCount - 1; ++i) {
vExcelApp.OlePropertyGet("Rows", i+2).OlePropertySet("RowHeight", 16);
vSheet.OlePropertyGet("Cells", i+2, 1)
.OlePropertySet("Value", lv->Items->Item[i]->Caption.c_str());
for (int j = 0; j < lv->Items->Item[i]->SubItems->Count; ++j) {
vSheet.OlePropertyGet("Cells", i+2, j+2)
.OlePropertySet("Value",
lv->Items->Item[i]->SubItems->Strings[j].c_str());
}
}
vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", strXlsFile.c_str());
vExcelApp.OleFunction("Quit");
vSheet = Unassigned; vExcelApp = Unassigned;
MessageBox(0, "ListView2Excel 轉換完成!", "ListView2Excel", MB_OK|MB_ICONINFORMATION);
}
ListView2Word(ListView1, "C:\\Export\\Report.doc");
ListView2Excel(ListView1, "C:\\Export\\Report.xls");
Range.Value = SafeArraytry-catch 並記錄錯誤日誌