在C++Builder中使用OLE的方式把数据库表中(TDBGrid)的内容保存到Excel的学习过程中,跟“ccrun(老妖) info@ccrun.com”学习了很多(致敬ccrun(老妖))。
后来增加了把TStringList中的内容保存到Excel,重复向每个cell填充,这个方法的缺点是太慢。也可以一次填充一行(未实现)。下面是示意代码:
System::Variant vExcelApp;
System::Variant vSheet;
String strXlsFile;
try
{
vExcelApp = System::Variant::CreateObject("Excel.Application");
}
catch (...)
{
MessageBox(0, "启动 Excel 出错, 可能是没有安装Excel.", "DBGrid2Excel", MB_OK | MB_ICONERROR);
return true;
}
// 隐藏Excel界面
// vExcelApp.OlePropertySet("Visible", false);
vExcelApp.OlePropertySet("Visible", true);
vSheet = vExcelApp.OlePropertyGet("ActiveSheet");
TStringList *strList;
strList=new TStringList;
strList->Add("123");
strList->Add("abc");
AnsiString str;
str=strList->Strings[0];
vSheet.OlePropertyGet("Cells", 1, 1).OlePropertySet("Value", WideString(str));
str=strList->Strings[1];
vSheet.OlePropertyGet("Cells", 1, 2).OlePropertySet("Value", WideString(str));
delete strList;
// 保存Excel文档并退出
try
{
if (FileExists(strXlsFile)) // 如果文件存在,就删除
{
DeleteFile(strXlsFile.c_str());
}
/*
vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs",
WideString(lpXlsFile),
-4143, // FileFormat:=xlExcel8,
WideString(""), // Password:="",
WideString(""), // WriteResPassword:="", _
false, // ReadOnlyRecommended:=False,
false // CreateBackup:=False
);
*/
// FileFormat:=xlExcel8 ,Excel 97-2003格式文件
vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", WideString(strXlsFile).c_bstr(), -4143);
vExcelApp.OleFunction("Quit");
vExcelApp = Unassigned;
}
catch (...)
{
vExcelApp = Unassigned;
return;
}
最近看到sprbreeze(Delhpi利用剪贴板快速导出(复制)数据到excel_sprbreeze的专栏-优快云博客)等人的相关文章,可以把用tab键间隔的TStringList内容拷贝到剪贴板后,再复制到excel中,速度要快很多,因此参考该方式,增加直接拷贝的方式把数据存到excel中,测试过程中,不定时不定点(有时卡在这里,下一个就可能在另外一个地方)出现“类worksheet的paste方法无效”的错误。后来猜测是不是excel还没有反应过来,于是在语句中增加Sleep(1000),休眠1秒(或者300毫秒等其他间隔),就不再出现该错误。
System::Variant vExcelApp;
System::Variant vSheet;
String strXlsFile;
try
{
vExcelApp = System::Variant::CreateObject("Excel.Application");
}
catch (...)
{
MessageBox(0, "启动 Excel 出错, 可能是没有安装Excel.", "DBGrid2Excel", MB_OK | MB_ICONERROR);
return true;
}
// 隐藏Excel界面
// vExcelApp.OlePropertySet("Visible", false);
vExcelApp.OlePropertySet("Visible", true);
TStringList *strList;
strList=new TStringList;
strList->Add("123 \t 456 \t 789");// 空格可以没有,用\t表示从输出tab
strList->Add("abc \t rt \t hj \t klp"); // 空格可以没有,用\t表示从输出tab
Clipboard()->Clear();
Clipboard()->AsText = saveCSV->Text;
vSheet = vExcelApp.OlePropertyGet("ActiveSheet");
vSheet.OleProcedure("Activate");
vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select");
// 没有这句,经常出现“类worksheet的paste方法无效”的错误
Sleep(300); // 休眠300毫秒,或者1000毫秒
vSheet.OleFunction("Paste");
// vSheet.OleProcedure("Paste"); // 用这个函数也行
delete strList;
// 保存Excel文档并退出
try
{
if (FileExists(strXlsFile)) // 如果文件存在,就删除
{
DeleteFile(strXlsFile.c_str());
}
/*
vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs",
WideString(lpXlsFile),
-4143, // FileFormat:=xlExcel8,
WideString(""), // Password:="",
WideString(""), // WriteResPassword:="", _
false, // ReadOnlyRecommended:=False,
false // CreateBackup:=False
);
*/
// FileFormat:=xlExcel8 ,Excel 97-2003格式文件
vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", WideString(strXlsFile).c_bstr(), -4143);
vExcelApp.OleFunction("Quit");
vExcelApp = Unassigned;
}
catch (...)
{
vExcelApp = Unassigned;
return;
}
当然,还有一种不用OLE的快速保存为excel文件的方法,就是保存为csv格式的文本文件,数据之间用逗号(,)间隔,这样用excel打开即可,缺点是不能分sheet保存为excel文件。