1、MFC中使用EXCEL方法及源码1使用MFC操作EXCEL文件一、加载1、 在VC6.0里创建一个MFC工程2、打开MFC ClassWizard窗口(查看建立类向导),选择Automation,单击Add Class按钮,选择From a type library.,弹出文件选择对话框,之后定位到C:Program FilesMicrosoft OfficeOFFICE11EXCEL.EXE,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。3、返回编辑器,查看工程文件,可发现多了EXCEL.H及EXCEL.CPP两个文件,拷贝出来,放在VS2005需要使用
2、excel的工程文件中。4. 打开stdafx.h头文件确保包含如下头文件:#include (这个一般有了)#include excel.h (手动添加这个即可)5. 打开TestExcel.cpp文件,修改CTestExcelApp:InitInstance(),加入如下代码:if( !AfxOleInit() )AfxMessageBox(初始化Ole出错!);return FALSE;为保证编译时不产生重复定义错误(可以验证一下是否成功加载,没有也能正常执行),我编译时出现了很多“类重复定义”异常,打开excel.h文件,在文件开始位置加入如下代码:#if !defined _HEAD
3、_FILE_EXCEL9_#define _HEAD_FILE_EXCEL9_相应的,在文件末尾加入:#endif成功二、操作EXCEL文件1. 新建一个excel表,并填充两个单元格的实例void CTestExcelDlg:OnButton1()/WorkbooksWorkbook WorksheetsWorksheet Range_Application app; /Excel应用程序接口Workbooks books; /工作薄集合_Workbook book; /工作薄Worksheets sheets; /工作表集合_Worksheet sheet; /工作表Range range
4、; /Excel中针对单元格的操作都应先获取其对应的Range对象Font font;Range cols;/*COleVariant类为VARIANT数据类型的包装,在自动化程序中,通常都使用VARIANT数据类型进行参数传递。故下列程序中,函数参数都是通过COleVariant类来转换了的。*/covOptional 可选参数的VARIANT类型COleVariant covOptional(long)DISP_E_PARAMNOTFOUND, VT_ERROR);if( !app.CreateDispatch(Excel.Application) )this-MessageBox(无法创
5、建Excel应用!);return;/获取工作薄集合books=app.GetWorkbooks();/添加一个工作薄book=books.Add(covOptional);/获取工作表集合sheets=book.GetSheets();/获取第一个工作表sheet=sheets.GetItem(COleVariant(short)1);/选择工作表中A1:A1单元格区域range=sheet.GetRange(COleVariant(A1),COleVariant(A1);/设置A1=HELLO EXCEL!range.SetValue(COleVariant(HELLO EXCEL!);/
6、调整格式,设置粗体font=range.GetFont();font.SetBold(COleVariant(short)TRUE);/选择A2单元格,插入一个公式=RAND()*,并设置A2数字格式为货币形式range=sheet.GetRange(COleVariant(A2),COleVariant(A2);range.SetFormula(COleVariant(=RAND()*);range.SetNumberFormat(COleVariant($0.00);/选择A:A列,设置宽度为自动适应cols=range.GetEntireColumn();cols.AutoFit();/
7、显示Excel表格,并设置状态为用户可控制app.SetVisible(TRUE);app.SetUserControl(TRUE);2. 打开一个已有的excel表格实例CString filename; CFileDialog dlg(TRUE,/TRUE是创建打开文件对话框,FALSE则创建的是保存文件对话框 .xls,/默认的打开文件的类型 NULL,/默认打开的文件名 OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,/打开只读文件 NULL);/所有可以打开的文件类型 if(dlg.DoModal()=IDOK) filename = dlg.GetPa
8、thName();/取出文件路径 / CString m_path; /m_path=m_FilePath;/将文件的路径放入m_path UpdateData(FALSE); CString strPath; strPath += C:template.xlt; / 模板的路径 CFileFind filefind; if( !filefind.FindFile( strPath ) ) AfxMessageBox( 没有找到模版文档,请其查找 ); return; LPDISPATCH lpDisp; /接口指针books=app.GetWorkbooks();lpDisp = books
9、.Open(m_filepath, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional ); /与的不同,是个参数的,直接在后面加了两个covOptional成功了book.AttachDispatch(lpDisp);/显示Excel表格,并设置状态为用户可控制app.SetVisibl
10、e(TRUE);app.SetUserControl(TRUE);3. 保存一个excel文件实例book.SetSaved(TRUE);4. 另存一个excel文件实例book.SaveAs(COleVariant(m_filename),covOptional, covOptional,covOptional, covOptional,covOptional,(long)0,covOptional,covOptional,covOptional,covOptional,covOptional); /与的不同,是个参数的,直接在后面加了两个covOptional成功了5. 释放一个excel
11、文件实例经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错)/释放对象(相当重要!) Rang.ReleaseDispatch(); sheet.ReleaseDispatch(); sheets.ReleaseDispatch(); book.ReleaseDispatch(); books.ReleaseDispatch(); /退出程序 app.Quit();/m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错 app.Rele
12、aseDispatch(); 6. 修改一个excel单元格range=sheet.GetRange(COleVariant(IndexToString(row,col),COleVariant(IndexToString(row,col);range.SetValue2(COleVariant(value);7. 取出一个excel单元格实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。range=sheet.GetRange(COleVariant(IndexToString(row,col),COleVariant(IndexToString(row,co
13、l);COleVariant rValue;rValue=COleVariant(range.GetValue2();rValue.ChangeType(VT_BSTR);return CString(rValue.bstrVal);8. 还有释放问题是最重要的问题: 首先变量必须全释放,无论当初是否绑定过; 其次,程序释放和程序关闭的顺序必须是app.Quit();app.ReleaseDispatch();如果顺如颠倒如下:app.ReleaseDispatch();app.Quit();出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。附录(操作
14、类源码):#include ./Stdafx.h#include OptExcel.h#include excel.h#include comdef.h _Application app;Workbooks books;_Workbook book;Worksheets sheets;_Worksheet sheet;Range range;Range cell;Font font;COleVariant covOptional(long)DISP_E_PARAMNOTFOUND, VT_ERROR);/Function: COptExcel/Description: 初始化函数,初始化中附加
15、excel应用程序/Call: app.CreateDispatch(_T(Excel.Application)/COptExcel:COptExcel(void) if (:CoInitialize( NULL ) = E_INVALIDARG) AfxMessageBox(_T(初始化Com失败!); return; /验证office文件是否可以正确运行 if( !app.CreateDispatch(_T(Excel.Application) ) AfxMessageBox(_T(无法创建Excel应用!); return; /在程序执行文件路径名中,剪掉执行文件名,得到程序路径,追加
16、模板文件名,得到模板完整路径 /Function: COptExcel/Description: 析构函数,释放对象,非常重要,不全部释放,占用内存,下/ 一次使用此类时会中断/Call: ReleaseDispatch()/COptExcel:COptExcel(void) books.ReleaseDispatch(); book.ReleaseDispatch(); sheets.ReleaseDispatch(); sheet.ReleaseDispatch(); range.ReleaseDispatch(); font.ReleaseDispatch(); cell.Release
17、Dispatch(); app.Quit(); app.ReleaseDispatch(); :CoUninitialize();/Function: OpenExcelBook/Description: 打开表名为filename的文件,注意,文件路径非自动生成,以后/ 考虑从下处理方法/Call: GetAppPath()/Input: CString filename 文件名/bool COptExcel:OpenExcelBook(CString filename) CFileFind filefind; if( !filefind.FindFile(filename) ) AfxMe
18、ssageBox(_T(文件不存在); return false; LPDISPATCH lpDisp; /接口指针 books=app.GetWorkbooks(); lpDisp = books.Open(filename, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional ); /
19、与office 2000的不同,是个参数的,直接在后面加了两个covOptional成功了 book.AttachDispatch(lpDisp); sheets=book.GetSheets(); sheet=sheets.GetItem(COleVariant(short)1); /与的不同,是个参数的,直接在后面加了两个covOptional成功了/显示Excel表格,并设置状态为用户可控制app.SetVisible(TRUE);app.SetUserControl(TRUE); return true;void COptExcel:NewExcelBook() books=app.G
20、etWorkbooks(); book=books.Add(covOptional); sheets=book.GetSheets(); sheet=sheets.GetItem(COleVariant(short)1); /与的不同,是个参数的,直接在后面加了两个covOptional成功了/Function: OpenExcelApp/Description: 打开应用程序(要注意以后如何识别用户要打开的是哪个文件)/void COptExcel:OpenExcelApp(void) app.SetVisible(TRUE); app.SetUserControl(TRUE);/Funct
21、ion: SaveExcel/Description: 用于打开数据文件,续存数据后直接保存/void COptExcel:SaveExcel(void) book.SetSaved(TRUE);/Function: SaveAsExcel/Description: 保存excel文件/void COptExcel:SaveAsExcel(CString filename) book.SaveAs(COleVariant(filename),covOptional, covOptional,covOptional, covOptional,covOptional,(long)0,covOpti
22、onal,covOptional,covOptional, covOptional,covOptional); /Function: SetCellValue/Description: 修改单元格内的值/Call: IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串/Input: int row 单元格所在行/ int col 单元格所在列/ int Align 对齐方式默认为居中/void COptExcel:SetCellValue(int row, int col,int Align) range=sheet.GetRange(COleVariant(Index
23、ToString(row,col),COleVariant(IndexToString(row,col); range.SetValue2(COleVariant(value); cell.AttachDispatch(range.GetItem (COleVariant(long(1), COleVariant(long(1).pdispVal); cell.SetHorizontalAlignment(COleVariant(short)Align);/Function: GetCellValue/Description: 得到的单元格中的值/Call: IndexToString() 从
24、(x,y)坐标形式转化为“A1”格式字符串/Input: int row 单元格所在行/ int col 单元格所在列/Return: CString 单元格中的值/CString COptExcel:GetCellValue(int row, int col) range=sheet.GetRange(COleVariant(IndexToString(row,col),COleVariant(IndexToString(row,col); COleVariant rValue; rValue=COleVariant(range.GetValue2(); rValue.ChangeType(
25、VT_BSTR); return CString(rValue.bstrVal);/Function: SetRowHeight/Description: 设置行高/Call: IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串/Input: int row 单元格所在行/void COptExcel:SetRowHeight(int row, CString height) int col = 1; range=sheet.GetRange(COleVariant(IndexToString(row,col),COleVariant(IndexToString(row,col); range.SetRowHeight(COleVariant(height);/Function: SetColumnWidth/Description: 设置列宽/Call