分享
 
 
 

在C++ Builder中用Ole控制Excel表

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

笔者在实际工作中经常用Excel表做数据报表,大多数表格的数据都要从数据库中读取,这样我就用C++Builder做了一个报表程序,方便了很多,现在把它共享给C++Builder爱好者们,就算为丰富C++Builder的文档资料做点事情吧。

首先把Excel报表文件保存到一个指定目录下,最好放在可执行程序的子目录下,作为模板文件。可以把报表标题、表头等设置好。这里是保存在trpt子目录下。

然后建一个report目录,作为报表目标文件夹,存放填好数据的报表,可以由用户直接操作。

首先确定在你的机器中装有Office。这里一Office2000为例。

在C++Builder中新建一个工程,在窗体Form1上面放一个两个按钮SaveButton和ReadButton,分别用来保存数据到Excel表和显示刚刚保存的Excel表。

在SaveButton按钮的单击事件中把从数据库中取到的数据放入到指定的Excel表中并将改文件拷贝到report目录下。在ReadButto按钮的单击事件中显示report目录下的报表文件,方便用户修改和另外保存。

在Form1.h头文件中定义几个变量:

private:

Variant Ex,Wb,Sheet,ERange,EBorders;

并在文件头中包含如下语句:

#include "Excel_2K_SRVR.h"

#include

在Form1.cpp的文件头中加入

#pragma link "Excel_2K_SRVR"

主要代码如下:

void __fastcall TForm1:: SaveButtonClick(TObject *Sender)

{

try

{

SaveButton->Enabled = false;

ReadButton->Enabled = false;//使两个按钮无效

file://取报表文件CardSend.xls的完整目录名

AnsiString ExcelFileName = GetCurrentDir()+"\\trpt\\table.xls";

if(!FileExists(ExcelFileName))

{

Application->MessageBox("报表模板文件不存在,无法打开!",

"错误",MB_ICONSTOP|MB_OK);

return;

}

file://建立Excel的Ole对象Ex

try

{

Ex = Variant::CreateObject("Excel.Application");

}

catch(...)

{

Application->MessageBox("无法启动Excel","错误",MB_ICONSTOP|MB_OK);

return;

}

file://设置Excel为不可见

Ex.OlePropertySet("Visible",false);

file://打开指定的Excel报表文件。报表文件中最好设定只有一个Sheet。

Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());

Wb = Ex.OlePropertyGet("ActiveWorkBook");

Sheet = Wb.OlePropertyGet("ActiveSheet");//获得当前默认的Sheet

file://清空Excel表,这里是用循环清空到第300行。对于一般的表格已经足够了。

AnsiString strRowTemp;

AnsiString strRange;

int iCols,iRows;//记录列数和行数

/*从第三行开始,到第300行止。一般第一行是表标题,第二行是副标题或者制表日期。*/

for(iRows=3;iRows<300;iRows++)

{ file://假设只有6列。

for (iCols = 1;iCols < 7; iCols++)

{

file://清空行

Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value","");

}

file://去掉表格边框

strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);//获取操作范围

ERange = Sheet.OlePropertyGet("Range",strRange.c_str());

EBorders = ERange.OlePropertyGet("Borders");//获取边框对象

EBorders.OlePropertySet("linestyle",xlNone);

}

AnsiString strPtrDate; file://存放当前日期,作为制表日期

DateSeparator = '-';

ShortDateFormat = "yyyy/m/d";//设置为年/月/日格式

strPtrDate = DateToStr(Date());//取当前日期

AnsiString strYear = strPtrDate.SubString(1,4);

strPtrDate = strPtrDate.SubString(6,strPtrDate.Length()-5);

AnsiString strMonth = strPtrDate.SubString(1,strPtrDate.Pos("-")-1);

AnsiString strDay =

strPtrDate.SubString(strPtrDate.Pos("-")+1,

strPtrDate.Length()-strPtrDate.Pos("-"));

strPtrDate = strYear+"年"+strMonth+"月"+strDay+"日";

AnsiString strData = "报表标题";//报表标题

file://将报表标题置于第一行第一列。在此之前,应将报表文件的标题格式设定好。

Sheet.OlePropertyGet("Cells",1,1).OlePropertySet("Value",

strData.c_str());

file://将制表日期置于表格第二行的右侧。

Sheet.OlePropertyGet("Cells",2,5).OlePropertySet("Value",

strPtrDate.c_str());

iRows = 3;//在第三行放置表格的列名

Sheet.OlePropertyGet("Cells",iRows,1).OlePropertySet("Value","列名1");

Sheet.OlePropertyGet("Cells",iRows,2).OlePropertySet("Value","列名2");

Sheet.OlePropertyGet("Cells",iRows,3).OlePropertySet("Value","列名3");

Sheet.OlePropertyGet("Cells",iRows,4).OlePropertySet("Value","列名4");

Sheet.OlePropertyGet("Cells",iRows,5).OlePropertySet("Value","列名5");

Sheet.OlePropertyGet("Cells",iRows,6).OlePropertySet("Value","列名6");

file://画表格边框,在A3:F3之间取范围

strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);

ERange = Sheet.OlePropertyGet("Range",strRange.c_str());

EBorders = ERange.OlePropertyGet("Borders");

EBorders.OlePropertySet("linestyle",xlContinuous);

EBorders.OlePropertySet("weight",xlThin);

EBorders.OlePropertySet("colorindex",xlAutomatic);

iRows++;

file://从数据库中取数据(略),假设数据集放入Query1中。

Query1->Open();//打开数据集

file://循环取数

while(!Query1->Eof)

{

file://循环取字段的数据放到Excel表对应的行列中

for(iCols=1;iCols<7;iCols++)

{

strRowTemp = Query1->Fields->Fields[iCols-1]->AsString;

Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value",

strRowTemp.c_str());

}

file://画该行的表格边框

strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);

ERange = Sheet.OlePropertyGet("Range",strRange.c_str());

EBorders = ERange.OlePropertyGet("Borders");

EBorders.OlePropertySet("linestyle",xlContinuous);

EBorders.OlePropertySet("weight",xlThin);

EBorders.OlePropertySet("colorindex",xlAutomatic);

iRows++;

Query1->Next();

}//while结束

Wb.OleProcedure("Save");//保存表格

Wb.OleProcedure("Close");关闭表格

Ex.OleFunction("Quit");退出Excel

file://定义目标文件名

AnsiString DestinationFile =

GetCurrentDir()+"\\report\\table.xls";

file://将刚刚修改的Excel表格文件table.xls拷贝到report目录下

if(!CopyFile(ExcelFileName.c_str(),DestinationFile.c_str(),false))

{

Application->MessageBox("复制文件操作失败,Excel文件可能正在使用中!",

"错误",MB_ICONSTOP|MB_OK);

return;

}

Application->MessageBox("成功完成报表保存!\n可以按\'打开Excel文件\'

按钮进行报表工作","提示",MB_ICONINFORMATION|MB_OK);

SaveButton ->Enabled = true;

ReadButton ->Enabled=true;

}//try结束

catch(...)

{

Application->MessageBox("操作Excel表格失败!",

"错误",MB_ICONSTOP|MB_OK);

Wb.OleProcedure("Close");

Ex.OleFunction("Quit");

SaveButton ->Enabled = true;

ReadButton ->Enabled=false;

}

}

至此,完成报表数据的写入工作。如果要对完成的Excel表进行操作,可以点击"打开Excel表文件按钮"(ReadButton),进行修改,保存,打印等操作。ReadButton的单击事件如下实现:

void __fastcall TForm1:: ReadButtonClick(TObject *Sender)

{

try

{

file://指定report目录下的报表文件用于用户操作

AnsiString ExcelFileName =

GetCurrentDir();+"\\report\\table.xls";

if(!FileExists(ExcelFileName))

{

Application->MessageBox("Excel表文件不存在,无法打开!",

"错误",MB_ICONSTOP|MB_OK);

return;

}

try

{

Ex = Variant::CreateObject("Excel.Application");

}

catch(...)

{

Application->MessageBox("无法启动Excel","错误",MB_ICONSTOP|MB_OK);

return;

}

file://使Excel可见

Ex.OlePropertySet("Visible",true);

file://打开Excel表格文件Table.xls

Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());

}

catch(...)

{

Application->MessageBox("操作Excel表格错误!","错误",MB_ICONSTOP|MB_OK);

Ex.OleFunction("Quit");

}

}

以上关于C++BuilderExcel表格的操作仅作为个人观点和水平呈献给关心此问题的读者,如果有更好的方式方法,敬请指教,不胜感激。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有