if ( SaveDialog->Execute() /*SelectDirectory("请选择存储目录","",Dir)*/ )
{
ExportToExcel( DBGrid,/*Dir*/ SaveDialog->FileName);
}
/*****************************************************
函数说明: 讲DBGrid的数据导出到Excel中
参 数: *dbg 指向要导出的TDBGrid对象,saveDir保存的路径
备 注:数据的写入用了windows的粘贴板做暂存后再粘贴到excel,
这样减少重复多次的读写操作,缩减导出时间。
另外Excel一个sheet只能有65536行,如果导出的数据行数
多于65530行(6行用掉了)应该要存到多个sheet,目前没有实现。
******************************************************/
void TF_report::ExportToExcel(TDBGrid *dbg, String saveDir)
{
/*************************************************************
以下为TExcelApplication、TExcelWorkbook、TExcelWorksheet方法
虽然比较推荐,但是Excel进程只能在关闭窗体后才会退出,找不到
导完数据后关闭的方法。
***********************************************************/
try
{
ExcelApplication->Connect();
ExcelApplication->set_DisplayAlerts(0,false);
}
catch(...)
{
MessageBox(0, "启动 Excel 出错,可能你没有安装Office .",
"导出错误", MB_OK | MB_ICONERROR);
return;
}
try
{
// 隐藏Excel界面
ExcelApplication->set_Visible(0,false);
}
catch (...)
{
MessageBox(0, "启动 Excel 出错 .",
"导出错误", MB_OK | MB_ICONERROR);
ExcelApplication->Disconnect();
ExcelApplication->Quit();
return;
}
//载入模板
String xls = ExtractFilePath(Application->ExeName) + "Template.xls";
if( !FileExists(xls) )
{
MessageBox(0, "Excel模板文件不存在,请重新安装外接软件!",
"导出错误", MB_OK | MB_ICONERROR);
ExcelApplication->Disconnect();
ExcelApplication->Quit();
return;
}
try
{
// 载入模板到Excel
WideString wxls = xls;
ExcelWorkbook->ConnectTo(ExcelApplication->Workbooks->Open(wxls.c_bstr(),
TNoParam(),TNoParam(),TNoParam(),TNoParam(),
TNoParam(),TNoParam(),TNoParam(),TNoParam(),
TNoParam(),TNoParam(),TNoParam(),TNoParam(),0));
}
catch( ... )
{
MessageBox(0, "Excel模板载入错误!",
"导出错误", MB_OK | MB_ICONERROR);
ExcelWorkbook->Disconnect();
ExcelApplication->Disconnect();
ExcelApplication->Quit();
return;
}
try
{
// 操作这个工作表
ExcelWorksheet->ConnectTo( ExcelWorkbook->Worksheets->get_Item( TVariant(1) ) );
// 表格的行数
int nRowCount(dbg->DataSource->DataSet->RecordCount);
nRowCount = nRowCount < 2? 2: nRowCount;
if( nRowCount > 65530 )
{
ShowMessage("记录多于65530条,受Excel的工作表限制,将只导出前65530条。");
nRowCount = 65530;
}
//插入nRowCount-1行
for ( int i = 0; i < nRowCount -1 ; ++i)
{
Excel_2k::RangePtr rp;
rp = ExcelWorksheet->get_Range(TVariant("A3"),TVariant("A3"));
rp->EntireRow->Insert(TNoParam());
}
// 表格的列数
int nColCount(dbg->Columns->Count);
nColCount = nColCount < 1? 1: nColCount;
// 将DBGrid中的数据写入Excel表格
int pcount = 0 , unpcount;
String qual,rate,value,cell;
char ct;
// cell = "A" + IntToStr(1);
// value = "我是标题";
// ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );
TStringList *sl=new TStringList();
dbg->DataSource->DataSet->First();
for(int i=0; i<nRowCount; i++)
{
value = "";
for(int j=0; j<nColCount; j++)
{
if( j != 1)
{
// value = dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsString;
value += Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsString) + "/t";
}
else
{ //DBGrid显示时间时自动加上了一个日期,在显示和导出时需要格式化,去掉日期( PS:显示用了字典格式化)
// value = FormatDateTime("hh:nn:ss",dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsDateTime);
value += FormatDateTime("hh:nn:ss", Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsDateTime) ) + "/t";
}
// ct = static_cast<char>('A' + j);
// cell = ct ;
// cell += IntToStr(i + 3);
// ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );
}
sl->Add(value); //TStringList自动在末尾加上 /n 换行符
qual = Trim(dbg->DataSource->DataSet->FieldByName("Test_qual")->AsString);
if( qual == "合格")
pcount++;
dbg->DataSource->DataSet->Next();
}
Clipboard()->SetTextBuf(sl->Text.c_str()); //发送到粘贴板
ExcelWorksheet->get_Range(TVariant("A3"),TVariant("A3"))->Select();
ExcelWorksheet->Paste();
ExcelWorksheet->get_Range(TVariant("A1"),TVariant("A1"))->Select();
Clipboard()->Clear(); //清除粘贴板
unpcount = nRowCount - pcount;
rate = FormatFloat("0.00",100.0f*pcount/nRowCount);
rate += "%";
//设置总个数
value = IntToStr(nRowCount);
ct = static_cast<char>('A' + 3);
cell = ct;
cell += IntToStr(nRowCount + 4);
ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );
//合格个数
value = IntToStr(pcount);
ct = static_cast<char>('A' + 8);
cell = ct;
cell += IntToStr(nRowCount + 4);
ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );
//不合格个数
value = IntToStr(unpcount);
ct = static_cast<char>('A' + 10);
cell = ct ;
cell += IntToStr(nRowCount + 4);
ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );
//合格率
value = rate;
ct = static_cast<char>('A' + 12);
cell = ct;
cell += IntToStr(nRowCount + 4);
ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );
WideString Dir = saveDir;
ExcelWorksheet->SaveAs(Dir.c_bstr(),
TNoParam(),TNoParam(),TNoParam(),TNoParam(),
TNoParam(),TNoParam(),TNoParam(),TNoParam(),0);
}
catch( ... )
{
ExcelWorksheet->Disconnect();
ExcelWorkbook->Disconnect();
ExcelApplication->Disconnect();
ExcelApplication->Quit();
ExcelQueryTable->Disconnect();
return;
}
ExcelWorksheet->Disconnect();
ExcelWorkbook->Disconnect();
ExcelApplication->Disconnect();
ExcelQueryTable->Disconnect();
ExcelApplication->Quit();
/*************************************************************
以下为OLE方法,编译时无法判断错误的Excel操作,
但能在导出后关闭Excel进程。
***********************************************************/
/*
Variant vExcelApp, vSheet,Range;
try
{
vExcelApp = Variant::CreateObject("Excel.Application");
}
catch(...)
{
MessageBox(0, "启动 Excel 出错,可能你没有安装Office .",
"导出错误", MB_OK | MB_ICONERROR);
return;
}
try
{
// 隐藏Excel界面
vExcelApp.OlePropertySet("Visible", false);
}
catch (...)
{
MessageBox(0, "启动 Excel 出错 .",
"导出错误", MB_OK | MB_ICONERROR);
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
return;
}
//载入模板
String xls = ExtractFilePath(Application->ExeName) + "Template.xls";
if( !FileExists(xls) )
{
MessageBox(0, "Excel模板文件不存在,请重新安装外接软件!",
"导出错误", MB_OK | MB_ICONERROR);
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
return;
}
try
{
// 载入模板到Excel
vExcelApp.OlePropertyGet("Workbooks").OleFunction("Open",xls.c_str()); // 工作表
}
catch( ... )
{
MessageBox(0, "Excel模板载入错误!",
"导出错误", MB_OK | MB_ICONERROR);
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
return;
}
// 操作这个工作表
vSheet = vExcelApp.OlePropertyGet("ActiveWorkbook").OlePropertyGet("Sheets", 1);
// 表格的行数
int nRowCount(dbg->DataSource->DataSet->RecordCount);
nRowCount = nRowCount < 2? 2: nRowCount;
//插入nRowCount-1行
for ( int i = 0; i < nRowCount -1 ; ++i)
{
vSheet.OlePropertyGet("Rows",3).OleProcedure("Insert");
}
// 表格的列数
int nColCount(dbg->Columns->Count);
nColCount = nColCount < 1? 1: nColCount;
if( nRowCount > 65530 )
{
ShowMessage("记录多于65530条,受Excel的工作表限制,将只导出前65530条。");
nRowCount = 65530;
}
S
TStringList *sl=new TStringList();
int pcount = 0 , unpcount;
String qual,rate,value ="";
dbg->DataSource->DataSet->First();
for(int i=0; i<nRowCount; i++)
{ value ="";
for(int j=0; j<nColCount; j++)
{
if( j != 1)
{
// value = dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsString;
value += Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsString) + "/t";
}
else
{ //DBGrid显示时间时自动加上了一个日期,在显示和导出时需要格式化,去掉日期( PS:显示用了字典格式化)
// value = FormatDateTime("hh:nn:ss",dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsDateTime);
value += FormatDateTime("hh:nn:ss",Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsDateTime)) + "/t";
}
// vSheet.OlePropertyGet("Cells", i + 3, j + 1).OlePropertySet("Value",value.c_str());
}
sl->Add(value);
qual = Trim(dbg->DataSource->DataSet->FieldByName("Test_qual")->AsString);
if( qual == "合格")
pcount++;
dbg->DataSource->DataSet->Next();
}
vExcelApp.Exec(PropertyGet("Range")<<"A3").Exec(Procedure("Select"));
Clipboard()->SetTextBuf(sl->Text.c_str()); //发送到粘贴板
vExcelApp.OlePropertyGet("ActiveSheet").OleProcedure("Paste");
vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select"); //去除粘贴造成的选区
Clipboard()->Clear(); //清除粘贴板
unpcount = nRowCount - pcount;
rate = FormatFloat("0.00",100.0f*pcount/nRowCount);
rate += "%";
//设置总个数
vSheet.OlePropertyGet("Cells", nRowCount + 4,4).OlePropertySet("Value",IntToStr(nRowCount).c_str());
//合格个数
vSheet.OlePropertyGet("Cells", nRowCount + 4,9).OlePropertySet("Value",IntToStr(pcount).c_str());
//不合格个数
vSheet.OlePropertyGet("Cells", nRowCount + 4,11).OlePropertySet("Value",IntToStr(unpcount).c_str());
//合格率
vSheet.OlePropertyGet("Cells", nRowCount + 4,13).OlePropertySet("Value",rate.c_str());
// 保存Excel文档并退出
try
{
vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", saveDir.c_str());
}
catch( ... )
{
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
return;
}
vExcelApp.OleFunction("Quit");
vSheet = Unassigned;
vExcelApp = Unassigned;
*/
// 工作结束
MessageBox(0, "导出成功",
"导出到Excel", MB_OK | MB_ICONINFORMATION);
}