Excel 为发人员提供了强大的外部接口,方便开发人员进行二次开发。最近笔者就采用 excel 的 automation 技术成功地解决了 excel 报表的自动生成功能.
首先给大家介绍一下报表创建模块的组成,如下图所示
模版文件。由于笔者设计的报表都是周期性的固定报表,做成模版更适合数据的读写操作和图表的生成,所以将全部的报表归纳整理生成了几类模版。
模版描述文件。主要纪录数据写在那个行那个列,那个图表对应什么类型的数据。它跟随模版文件的变更一起变更,时刻与模版文件保持同步,这样可以不必修改程序就能够更改输出报表的格式。
数据源描述文件。主要描述对应文件的源数据所在的那种数据库。
接下来给大家介绍一下程序操作 excel 的流程:
一、插入类型库
1、 在一个已有的 MFC 工程按 Ctrl + W 弹出 ClassWizard 对话框。
2、 Add Class.../From a type Library... 在 Office 目录中,找到你想使用的 Excel 类型库。若你安装的是 Offce2000 则选择安装目录下的 EXCEL9.OLB 文件进行倒入,生成的倒入文件名称叫做 excel9.h 和 excel9.cpp ;若你安装的时 office2003 则选择。选择安装目录下 EXCEL.exe 进行到入 , 生成的倒入文件时 excel.h 和 excel.cpp 。两者的部分接口有所不同。
3、 在弹出的对话框中选择要添加的类,具体选那些类要根据实际情况而定。当然你也可以全选
说明:类型库会给出 Excel 的全部接口类,可以根据需要挑选自己需要的类,但是一般情况下的 EXCEL 文的操作都会涉及以下的几个类 :_Application 、 WorkBooks 、 _WorkBook 、 WorkSheets 、 _WorkSheet 、 Range 。若涉及图表的操作还会涉及如下的几个类: ChartObjects 、 ChartObject 、 _Chart 、 Series
二、服务的启动和关闭
服务器的启动
_Workbook excelBook; Worksheets excelSheets; _Application excelApp; BOOL CreateApplication() ... { if ( ! excelApp.CreateDispatch( " Excel.Application " ,NULL)) ... { AfxMessageBox( " 创建Excel服务失败! " ); return FALSE; } excelApp.SetVisible(FALSE); excelApp.SetDisplayAlerts(FALSE); return TRUE; }
说明:
在此之前要添加 CoInitialize(NULL) 函数初始化 Com 接口。
关键词 "Excel.Application" 是启动 Excel 的 COM 服务的唯一标示。
SetVisible 函数表示运行的进程是否可见。
SetDisplayAlerts 函数表示是否忽略警告信息,比如提示“文件 xxx.xls 已经存在是否覆盖?” , 若 SetDisplayAlerts 的参数为 FALSE 则不出现提示信并默认覆盖。
服务的关闭
void DestroryApplication() ... { excelApp.Quit(); excelApp.ReleaseDispatch(); }
三、文件的打开与保存
文件的打开
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.GetWorksheets()); 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 进程必须杀掉该进程才算完整的退出。实现代码如下:
KillProgram(“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; PROCESSENTRY32 pe32; MODULEENTRY32 me32; if ( ! ExeName || ! ExeName[ 0 ]) 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 (PROCESSENTRY32); 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 (Process32Next(hProcessSnap, & pe32)); } CloseHandle(hProcessSnap); }
未完待续。。。。