摘 要: 介绍了在VC中结合Excel创建和打印格式比较复杂的报表的具体方法。
关键词: VC Excel 报表设计
在数据库管理系统的开发以及一些涉及到报表制作的应用领域,各种复杂格式的报表处理是一项烦琐的工作。目前利用计算机辅助制作各种报表的方法基本都是在VB环境下操作的。事实上,VC作为另外一种功能强大的开发工具,在数据管理和操作方面同样具有强大的功能,并提供了多种方式进行报表处理。例如可以先创建一个指向打印机的设备环境句柄,通过该句柄调用相关的绘图函数,绘制空报表模版,并动态填入数据,输出到打印机上。用这种方法制作格式简单的报表时很方便,但是当碰到格式复杂的报表时,用Excel的电子表格制作功能结合VC的强大数据处理能力,将大大简化复杂表格的设计制作工作。
1 实现方法
1.1 利用Excel创建报表的模版文件
Excel具有强大的电子表格制作功能,利用其单元格的拆分、合并和格式设定,可以方便、快捷地绘制空白表格文档,并可以随时根据实际情况,重新设定报表格式,生成满足用户要求的模版文件。例如,当需要打印成百上千张格式一致的学生信息统计表时,若需要改变表格格式,只需要将模版文件稍加修改即可。
生成的工作表中每个单元格都有相应的编号,如“A9”和“G3”分别代表工作表中的A列第9行和G列第3行所对应的单元格。像这样记录要填充内容的单元格编号与要填充的数据字段是必要的。例如,设计一个学生信息卡,其格式如图1所示。
工作表中需要填姓名、性别和民族数据的单元格对应列为C列,年龄、籍贯和政治面貌对应E列,入学时间、所在系别和专业对应G列,其中行的编号为4~6,这样就形成了一个模版文件。
在程序中不需要直接操作模版文件,只需要将模版文件拷贝到一个副本中进行操作即可。在VC中进行文件操作不如在VB中方便。一种方法是直接利用CFile 类的操作成员函数来实现,但操作复杂。另一种有效的方法是利用Win32 API函数来实现对于文件的操作,例如要向第1列空白单元格填充学生姓名、性别和民族数据,则具体实现代码如下:
int nOk;
char strSrc[ ]=″...\\student.xls\0″; //源文件路径,省略号代表文件所在的相对路径
char strDst[ ]=″...\\studentbak.xls\0″; //目标文件路径
char strTitle[ ]=″File copying″; //进度题头
SHFILEOPSTRUCT FileOp;
FileOp.hwnd=m_hWnd;
FileOp.wFunc=FO_COPY; //执行文件拷贝,将模版文件拷贝到临时文件中
FileOp.pFrom=strSrc;
FileOp.pTo=strDst;
FileOp.fFlags=FOF_ALLOWUNDO;
FileOp.hNameMappings=NULL;
FileOp.lpszProgressTitle=strTitle;
nOk=SHFileOperation(&FileOp);
if(nOk)
TRACE(″There is an error:%d\n″,nOk);
else
TRACE(″SHFileOperation finished successfully\n″);
if(FileOp.fAnyOperationsAborted)
TRACE(″Operation was aborted!\n″);
1.2 将数据放入模版文件副本相应单元格中
(1)在程序中导入mso9.dll、vbe6ext.olb和Excel9.olb库文件。
在需要调用Excel报表文档的程序代码所在的.Cpp文件头,加入下面的代码:
#import <mso9.dll> no_namespace rename(″Document-
Properties″,DocumentPropertiesXL″)
#import <vbe6ext.olb> no_namespace
#import <Excel9.olb> rename(″DialogBox″,″DialogBoxXL″)
rename(″RGB″,″RBGXL″) rename(″DocumentProperties″,
″DocumentPropertiesXL″) no_dual_interfaces
同时要在VC工具栏的工具菜单中点击“选择菜单”项,在弹出的选择对话框中选择目录标签,指定mso9.dll、vbe6ext.olb和Excel9.olb文件所在的目录,否则程序将会编译错误,提示找不到这些库文件。默认情况下mso9.dll和Excel9.olb文件在Office安装目录下,而vbe6ext.olb文件在系统文件夹的共享文件中的VBA目录下。
(2)声明并建立对Excel应用程序、工作簿和工作表对象变量的引用。
using namespace Excel;
_ApplicationPtr pXL;
pXL->CreateInstance(L″Excel.Application.9″);
//创建Excel应用实例
pXL->Visible=VARIANT_TRUE;
_WorkbooksPtr pBooks=pXL->Workbooks;
_WorkbookPtr pBook=pBooks->Open(″..\\studentbak.xls″);
//打开已创建的临时模版文件
_WorksheetPtr pSheet=pXL->ActiveSheet;//设定当前
//工作表
pSheet->Name=″student″;//命名当前工作表
(3)将数据填入工作表相应单元格。
如果要操作的数据在学生信息数据库的学生信息表中,则定义1个CRecordSet对象变量m_bSet,并用该变量操作数据库中的数据(有关数据库操作的细节见相关书籍)。给单元格赋值的具体代码如下:
m_bSet.MoveFirst( );
do { CString row;
char h [20];
_itoa(k,h,10);//将整形变量转换为字符变量
row=h;
CString nsc=″C″+″4″;//填充姓名的单元格编号
CString ahd=″C″+″5″;//填充性别的单元格编号
CString ymn=″C″+″6″;//填充民族的单元格编号
//在将上述字符串变量作为单元格编号使用以前,需要进
//行强制类型转化,否则将出错
_variant_t na,ma,ph;
na=(_variant_t) (nsc);
ma=(_variant_t) (ahd);
ph=(_variant_t) (ymn);
pSheet->Range[na]->Value=(_variant_t) (m_bSet.Stuname);
//填充学生姓名数据
pSheet->Range[ma]->Value=(_variant_t) (m_bSet.Stusex);
//填充学生性别
pSheet->Range[ph]->Value=(_variant_t) (m_bSet.Stunation);
//填充学生民族
m_bSet.MoveNext( );
} while(!m_bSet.IsEOF( ));
m_bSet.Close( );
程序将一直执行,直到把数据库中的数据读取完毕。
1.3 报表打印
试验报表数据填写完成后的打印工作可以用下面的语句直接实现。但注意在打印之前应对Excel临时文件执行一次保存操作。
pBook->Saved=VARIANT_TRUE;//保存文件
pSheet->PrintOut( );//打印报表
pBook->Close( );//关闭表单
pXL->Quit( );//退出Excel
由于打印工作是后台操作,因此用户看不到具体实现过程,只能看到报表从打印机中被打印出来。
2 结束语
报表制作和打印的方法多种多样,本文介绍了用VC结合Excel实现复杂报表制作的具体方法,该方法能高效、快捷地解决实际问题。
参考文献
1 徐雄.在VB中调用Excel实现票据套打.计算机应用, 2001;(9)
2 北京源江科技开发公司制作.Visual C++编程资源大全(光 盘版).北京:北京万水电子信息有限公司出版社,2001
3 官章全,唐小卫.Visual C++ 6.0编程实例详解.北京:电子工业出版社,2001