利用VC操作Excel生成图文报表_第1页
利用VC操作Excel生成图文报表_第2页
利用VC操作Excel生成图文报表_第3页
利用VC操作Excel生成图文报表_第4页
利用VC操作Excel生成图文报表_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、VC中利用Excel2003生成图文报表(内部资料 请勿外传)编 写:邵江日 期:2011-2-21检 查:日 期:审 核:日 期:批 准:日 期:武汉东健科技有限公司版权所有 不得复制文档变更记录序号变更(+/-)说明作者版本号日期批准12参考资料1.1 VC利用EXCEL模板实现报表打印的九大步骤#include "excel9.h" /使用EXCEL类需要包含的头文件#include "comdef.h" /使用EXCEL类需要包含的头文件(注:需要"excel9.h"和"excel9.cpp",是通过类向导

2、添加新类中的from a type library 到office安装目录下加载olb 文件 注意excel加载exe文件)第二步:创建对象_Application ExcelApp;Workbooks wbsMyBooks;_Workbook wbMyBook;Worksheets wssMysheets;_Worksheet wsMysheet;Range rgMyRge;第三步:创建EXCEL服务器/*创建EXCEL服务器*/if (!ExcelApp.CreateDispatch("Excel.Application", NULL)AfxMessageBox(&qu

3、ot;创建EXCEL服务器失败!");return;第四步:利用EXCEL模板创建EXCEL文档/strPath为模板的全路径名wbsMyBooks.AttachDispatch(ExcelApp.GetWorkbooks(), true);trywbMyBook.AttachDispatch(wbsMyBooks.Add(_variant_t(strPath);catch(.)AfxMessageBox("EXCEL模板打开失败,请检查文件是否存在!", MB_OK | MB_ICONSTOP);ExcelApp.Quit();return;第五步:关联对象/*

4、得到Worksheets*/wssMysheets.AttachDispatch(wbMyBook.GetWorksheets(), true);/*得到Worksheet1*/wsMysheet.AttachDispatch(wssMysheets.GetItem(_variant_t("sheet1"), true);/*得到全部Cells,此时,rgMyRge是cells的集合*/ rgMyRge.AttachDispatch(wsMysheet.GetCells(),true); 第六步:设置单元格的值rgMyRge.SetItem(_variant_t(long)

5、1),_variant_t(long)1),_variant_t("姓名"); /1*1rgMyRge.SetItem(_variant_t(long)1),_variant_t(long)2),_variant_t("QQ号"); /1*2rgMyRge.SetItem(_variant_t(long)2),_variant_t(long)1),_variant_t("风云在线"); rgMyRge.SetItem(_variant_t(long)2),_variant_t(long)2),_variant_t("2788

6、00584"); 第七步:打印预览ExcelApp.SetVisible(true);wbMyBook.PrintPreview(_variant_t(false); 第八步:退出EXCEL应用程序/*设置保存标志为已保存,则不会弹出保存模板对话框,实际上并未保存,只是认为的标志保存了,因为这里不需要保存*/wbMyBook.SetSaved(true);/*退出EXCEL应用程序*/ExcelApp.Quit();第九步:释放对象/*释放对象*/ rgMyRge.ReleaseDispatch(); wsMysheet.ReleaseDispatch(); wssMysheets.

7、ReleaseDispatch(); wbMyBook.ReleaseDispatch(); wbsMyBooks.ReleaseDispatch(); ExcelApp.ReleaseDispatch();1.2 VC操作EXCELExcel为发人员提供了强大的外部接口,方便开发人员进行二次开发。最近笔者就采用excel 的automation技术成功地解决了excel报表的自动生成功能首先给大家介绍一下报表创建模块的组成,如下图所示模版文件。由于笔者设计的报表都是周期性的固定报表,做成模版更适合数据的读写操作和图表的生成,所以将全部的报表归纳整理生成了几类模版。 模版描述文件。主要纪录数据

8、写在那个行那个列,那个图表对应什么类型的数据。它跟随模版文件的变更一起变更,时刻与模版文件保持同步,这样可以不必修改程序就能够更改输出报表的格式。 数据源描述文件。主要描述对应文件的源数据所在的那种数据库。 接下来给大家介绍一下程序操作excel的流程:一、插入类型库1、 在一个已有的MFC工程按Ctrl + W 弹出ClassWizard对话框。2、 Add Class.From a type Library. 在 Office 目录中,找到你想使用的Excel类型库。若你安装的是Offce2000则选择安装目录下的EXCEL9.OLB文件进行倒入,生成的倒入文件名称叫做excel9.h和e

9、xcel9.cpp;若你安装的时office2003则选择。选择安装目录下EXCEL.exe进行到入,生成的倒入文件时excel.h和excel.cpp。两者的部分接口有所不同。3、 在弹出的对话框中选择要添加的类,具体选那些类要根据实际情况而定。当然你也可以全选 说明:类型库会给出Excel的全部接口类,可以根据需要挑选自己需要的类,但是一般情况下的EXCEL文的操作都会涉及以下的几个类:_Application、WorkBooks、_WorkBook、WorkSheets、_WorkSheet、Range。若涉及图表的操作还会涉及如下的几个类:ChartObjects、ChartObjec

10、t、_Chart、Series 二、服务的启动和关闭 服务器的启动 _Workbook excelBook; Worksheets excelSheets; _Application excelApp; BOOL CreateApplication() . if (!excelApp.CreateDispatch("Excel.Application",NULL) . AfxMessageBox("创建Excel服务失败!"); return FALSE; excelApp.SetVisible(FALSE); excelApp.SetDisplayAl

11、erts(FALSE); return TRUE; 说明: 在此之前要添加CoInitialize(NULL)函数初始化Com接口。 关键词"Excel.Application"是启动Excel的COM服务的唯一标示。SetVisible函数表示运行的进程是否可见。SetDisplayAlerts函数表示是否忽略警告信息,比如提示“文件xxx.xls已经存在是否覆盖?”,若SetDisplayAlerts的参数为FALSE则不出现提示信并默认覆盖。 服务的关闭 void DestroryApplication() . excelApp.Quit(); excelApp.Re

12、leaseDispatch(); 三、文件的打开与保存 文件的打开 BOOL Open(char* pFileName) . Workbooks excelBooks; excelBooks.AttachDispatch(excelApp.GetWorkbooks(); LPDISPATCH lpDisp = excelBooks.Add(SV(pFileName); if(lpDisp = NULL) return FALSE; excelBook.AttachDispatch(lpDisp); excelSheets.AttachDispatch(excelBook.GetWorkshee

13、ts(); return TRUE; 文件的保存 void Save(char* pFile,_Worksheet exceSheet) . exceSheet.SaveAs(pFile,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing, vtMissing,vtMissing,vtMissing); 说明: 对于文件的保存2000版和2003版有所区别,2000版比2003版少了一个参数。四、操作的退出上面提到得服务的退出不代表文件就关闭了,当服务停止后内存中依然驻留着一个Excel.exe进程必须杀掉该进程才算完整的退出。实现代码如下: K

14、illProgram(“Excel.exe”);BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM lParam) . DWORD dwID; GetWindowThreadProcessId(hwnd,&dwID); if(dwID = (DWORD)lParam) . PostMessage(hwnd, WM_QUIT, 0, 0); return FALSE; return TRUE; void KillProgram(LPCSTR ExeName) . LPCSTR File; HANDLE hProcessSnap; PROCESSENTR

15、Y32 pe32; MODULEENTRY32 me32; if(!ExeName | !ExeName0) return; File = strrchr(ExeName, ''); if(File!=0) ExeName = File + 1; hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hProcessSnap = (HANDLE)-1) return; memset(&pe32, 0, sizeof(pe32); pe32.dwSize = sizeof(PROCESSENT

16、RY32); if(Process32First(hProcessSnap, &pe32) . do . memset(&me32, 0, sizeof(me32); me32.dwSize = sizeof(me32); File = strrchr(pe32.szExeFile, ''); File = File ? File+1 : pe32.szExeFile; if(strcmpi(File,ExeName) = 0) EnumWindows(WNDENUMPROC)EnumWinProc, pe32.th32ProcessID); while(Pro

17、cess32Next(hProcessSnap,&pe32); CloseHandle(hProcessSnap); 数据操作 1获取sheet。void GetSheet(char* pSheetName,_Worksheet& excelSheet) excelSheet.AttachDispatch(excelSheets.GetItem(_variant_t(pSheetName); _Worksheet dataSheet;GetSheet("数据",dataSheet);注意:sheet名称必须在文件中存在,否则程序抛出异常。为了适应不同文件的操

18、作,此处的sheet名称可通过配置文件进行动态配置。2.获取rangevoid GetRange(_Worksheet excelSheet,Range& excelRange) excelRange.AttachDispatch(excelSheet.GetCells();Range dataRange;GetRange(dataSheet,dataRange);3指定行列的数据获取#define LV(x) _variant_t(long(x)#define SV(x) _variant_t(x)。bool GetData(int row,int col)range.AttachD

19、ispatch(dataSheet.GetCells(); range.AttachDispatch(range.GetItem(LV(row),LV(col).pdispVal); COleVariant vResult =range.GetValue2();if(vResult.vt=VT_EMPTY) return false;return true;4.数据的填写Void SetValue(int row,int col,char* pData) dataRange.SetItem(LV(row),LV(col),SV(pData); 5.数据区域的拷贝假如有一个表格高度变量是dTab

20、leHeight,宽度变量是dTableWidth,将其拷贝若干份,每个表格之间相隔一行实现代码如下:Int row = 1Range rgMyRge2, rgMyRge3For(int I = 0 ; I < n;i+)rgMyRge2.AttachDispatch( dataRange.GetItem( COleVariant(long)(row) , COleVariant(long)1).pdispVal, true); rgMyRge3.AttachDispatch(rgMyRge2.GetResize(COleVariant(long)dTableHeight ),COleV

21、ariant(long) dTableWidth) ); rgMyRge3.Copy( dataRange.GetItem(LV(long)( row + dTableHeight),LV( long(1) ) ) );row = row + dTableHeight + 1;图表操作Excel提供了功能强大的图表处理功能,我们可以轻而易举的绘制各类统计报表。如下图所示我们将对局有固定模版的图表进行处理。 1 获得图表_Worksheet chartSheet;GetSheet("曲线图",chartSheet); void GetChart(_Worksheet exce

22、lSheet,int dChatNo,_Chart& excelChart) ChartObjects objCharts; ChartObject objChart; COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR); objCharts = excelSheet.ChartObjects(vOpt); objChart = objCharts.Item(COleVariant(short)dChatNo); excelChart.AttachDispatch( objChart.GetChart(),true);_Chart resu

23、ltchart;GetChart(chartSheet,ChartNo,resultchart); 注意:变量ChartNo表示图表的排序值,即属于一个sheet中的第几个图表,该排序值是根据用户创建图表的顺序自动生成的。2 设定曲线要实现曲线的,就必须准确的描述曲线。曲线描述信息是一个序列化的字符串,它包含四个部分,每个部分之间依靠逗号分隔:1 图表的title.2 图表的x周描述信息3 显示曲线所基于的数据区域描述4 单一图表内的曲线排序值(曲线id)其中某些项目可以不设,系统将取默认值,最终形成的序列化格式如下:=SERIES("示例",数据!$A$4:$A$34,数

24、据!$C$4:$C$34,1),也可以省略指定x坐标=SERIES("示例", ,数据!$C$4:$C$34,1)。void SetChartSeriesSource( _Chart excelChart , short series_id , char *pParamLine) Series oSeries; oSeries = excelChart.SeriesCollection(COleVariant(short)series_id); oSeries.SetFormula(pParamLine); char szParamLine1024; sprintf(rgn

25、line,"=SERIES("%s",%s!$%s$%d:$%s$%d,%d)", "数据",pDataName,pCol,row,pCol,dIndexRowi , 1);SetChartSeriesSource(excelChart , 1 , szParamLine);注意:设定的数据内不得出现没有值得现象。比如基于数据区域a1:a100形成一条曲线,若a30的位置无数据(指的是区域空而非零)则程序抛出异常。1.3 用VC结合Excel实现复杂报表的制作关键词:报表设计 摘   要: 介绍了在VC中结合Exc

26、el创建和打印格式比较复杂的报表的具体方法。关键词: VC  Excel  报表设计 在数据库管理系统的开发以及一些涉及到报表制作的应用领域,各种复杂格式的报表处理是一项烦琐的工作。目前利用计算机辅助制作各种报表的方法基本都是在VB环境下操作的。事实上,VC作为另外一种功能强大的开发工具,在数据管理和操作方面同样具有强大的功能,并提供了多种方式进行报表处理。例如可以先创建一个指向打印机的设备环境句柄,通过该句柄调用相关的绘图函数,绘制空报表模版,并动态填入数据,输出到打印机上。用这种方法制作格式简单的报表时很方便,但是当碰到格式复杂的报表时,用Excel的电子表格

27、制作功能结合VC的强大数据处理能力,将大大简化复杂表格的设计制作工作。1  实现方法1.1 利用Excel创建报表的模版文件Excel具有强大的电子表格制作功能,利用其单元格的拆分、合并和格式设定,可以方便、快捷地绘制空白表格文档,并可以随时根据实际情况,重新设定报表格式,生成满足用户要求的模版文件。例如,当需要打印成百上千张格式一致的学生信息统计表时,若需要改变表格格式,只需要将模版文件稍加修改即可。生成的工作表中每个单元格都有相应的编号,如“A9”和“G3”分别代表工作表中的A列第9行和G列第3行所对应的单元格。像这样记录要填充内容的单元格编号与要填充的数据字段是必要的。例如,设

28、计一个学生信息卡,其格式如图1所示。工作表中需要填姓名、性别和民族数据的单元格对应列为C列,年龄、籍贯和政治面貌对应E列,入学时间、所在系别和专业对应G列,其中行的编号为46,这样就形成了一个模版文件。 在程序中不需要直接操作模版文件,只需要将模版文件拷贝到一个副本中进行操作即可。在VC中进行文件操作不如在VB中方便。一种方法是直接利用CFile 类的操作成员函数来实现,但操作复杂。另一种有效的方法是利用Win32 API函数来实现对于文件的操作,例如要向第1列空白单元格填充学生姓名、性别和民族数据,则具体实现代码如下:int nOk;char strSrc =.student.xls0;/源

29、文件路径,省略号代表文件所在的相对路径char strDst =.studentbak.xls0;/目标文件路径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;nO

30、k=SHFileOperation(&FileOp);if(nOk)TRACE(There is an error:%dn,nOk);elseTRACE(SHFileOperation finished successfullyn);if(FileOp.fAnyOperationsAborted)TRACE(Operation was aborted!n);1.2  将数据放入模版文件副本相应单元格中(1)在程序中导入mso9.dll、vbe6ext.olb和Excel9.olb库文件。在需要调用Excel报表文档的程序代码所在的.Cpp文件头,加入下面的代码:#import

31、 <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工具栏的工具菜单中点击“选择菜单”项,在弹出的选择对话框中选择目录标签

32、,指定mso9.dll、vbe6ext.olb和Excel9.olb文件所在的目录,否则程序将会编译错误,提示找不到这些库文件。默认情况下mso9.dll和Excel9.olb文件在Office安装目录下,而vbe6ext.olb文件在系统文件夹的共享文件中的VBA目录下。(2)声明并建立对Excel应用程序、工作簿和工作表对象变量的引用。using namespace Excel;_ApplicationPtr pXL;pXL->CreateInstance(LExcel.Application.9);/创建Excel应用实例pXL->Visible=VARIANT_TRUE;_

33、WorkbooksPtr pBooks=pXL->Workbooks;_WorkbookPtr pBook=pBooks->Open(.studentbak.xls);/打开已创建的临时模版文件_WorksheetPtr pSheet=pXL->ActiveSheet;/设定当前/工作表pSheet->Name=student;/命名当前工作表(3)将数据填入工作表相应单元格。如果要操作的数据在学生信息数据库的学生信息表中,则定义1个CRecordSet对象变量m_bSet,并用该变量操作数据库中的数据(有关数据库操作的细节见相关书籍)。给单元格赋值的具体代码如下:m_

34、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->Rangena

35、->Value=(_variant_t) (m_bSet.Stuname);/填充学生姓名数据pSheet->Rangema->Value=(_variant_t) (m_bSet.Stusex);/填充学生性别pSheet->Rangeph->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. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论