使用MFC操作EXCEL文件
2015-08-12 14:31
411 查看
使用MFC操作EXCEL文件
分类: EXCEL 2012-09-03 09:30 14914人阅读 评论(5) 收藏 举报
excelmfcbooks工作applicationoffice
一、加载
1、 在VC6.0里创建一个MFC工程
2、打开MFCClassWizard窗口(查看—>建立类向导),选择Automation,单击AddClass按钮,选择Froma type library…,弹出文件选择对话框,之后定位到C:\Program Files\MicrosoftOffice\OFFICE11\EXCEL.EXE,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。
3、返回编辑器,查看工程文件,可发现多了EXCEL.9H及EXCEL9.CPP两个文件,拷贝出来,放在VS2005需要使用excel的工程文件中。
4. 打开stdafx.h头文件确保包含如下头文件:
为保证编译时不产生重复定义错误(可以验证一下是否成功加载,没有也能正常执行),我编译时出现了很多“类重复定义”异常,打开excel.h文件,在文件开始位置加入如下代码:
Excel接口
导入类
头文件
说明
_Application
CApplicaton
Application.h
Excel应用程序。
Workbooks
CWorkbooks
Workbooks.h
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
_Workbook
CWorkbook
Workbook.h
单个工作簿。
Worksheets
CWorksheets
Worksheets.h
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
_Worksheet
CWorksheet
Worksheet.h
单个Sheet表格。
Range
CRange
Range.h
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
在MSDN中,很少有excel方面的资料,但是在http://msdn.microsoft.com/zh-cn/ms348103.aspx中可以找到C#控制EXCEL方面的说明
二、操作EXCEL文件
1. 新建一个excel表,并填充两个单元格的实例
分类: EXCEL 2012-09-03 09:30 14914人阅读 评论(5) 收藏 举报
excelmfcbooks工作applicationoffice
一、加载
1、 在VC6.0里创建一个MFC工程
2、打开MFCClassWizard窗口(查看—>建立类向导),选择Automation,单击AddClass按钮,选择Froma type library…,弹出文件选择对话框,之后定位到C:\Program Files\MicrosoftOffice\OFFICE11\EXCEL.EXE,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。
3、返回编辑器,查看工程文件,可发现多了EXCEL.9H及EXCEL9.CPP两个文件,拷贝出来,放在VS2005需要使用excel的工程文件中。
4. 打开stdafx.h头文件确保包含如下头文件:
include
include “excel.h” (手动添加这个即可)
打开TestExcel.cpp文件,修改CTestExcelApp::InitInstance(),加入如下代码:[code]if(!AfxOleInit() ) { AfxMessageBox("初始化Ole出错!"); return FALSE; }
为保证编译时不产生重复定义错误(可以验证一下是否成功加载,没有也能正常执行),我编译时出现了很多“类重复定义”异常,打开excel.h文件,在文件开始位置加入如下代码:
if !defined HEAD_FILE_EXCEL9
define HEAD_FILE_EXCEL9
相应的,在文件末尾加入:endif
成功Excel接口
导入类
头文件
说明
_Application
CApplicaton
Application.h
Excel应用程序。
Workbooks
CWorkbooks
Workbooks.h
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
_Workbook
CWorkbook
Workbook.h
单个工作簿。
Worksheets
CWorksheets
Worksheets.h
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
_Worksheet
CWorksheet
Worksheet.h
单个Sheet表格。
Range
CRange
Range.h
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
在MSDN中,很少有excel方面的资料,但是在http://msdn.microsoft.com/zh-cn/ms348103.aspx中可以找到C#控制EXCEL方面的说明
二、操作EXCEL文件
1. 新建一个excel表,并填充两个单元格的实例
[code]void CTestExcelDlg::OnButton1() { //Workbooks—>Workbook —>Worksheets—>Worksheet —>Range _Application app; //Excel应用程序接口 Workbooks books; //工作薄集合 _Workbook book; //工作薄 Worksheets sheets; //工作表集合 _Worksheet sheet; //工作表 Range range; //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("无法创建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!")); //调整格式,设置粗体 font=range.GetFont(); font.SetBold(COleVariant((short)TRUE)); //选择A2单元格,插入一个公式"=RAND()*100000",并设置A2数字格式为货币形 式 range=sheet.GetRange(COleVariant("A2"),COleVariant("A2")); range.SetFormula(COleVariant("=RAND()*100000")); range.SetNumberFormat(COleVariant("$0.00")); //选择A:A列,设置宽度为自动适应 cols=range.GetEntireColumn(); cols.AutoFit(); //显示Excel表格,并设置状态为用户可控制 app.SetVisible(TRUE); app.SetUserControl(TRUE); 2. 打开一个已有的excel表格实例 [cpp] view plaincopy CString strPath; strPath += "C:\\template.xlt"; // 模板的路径 CFileFind filefind; if( !filefind.FindFile( strPath ) ) { AfxMessageBox( "没有找到模版文档,请其查找" ); return; } LPDISPATCH lpDisp; //接口指针 books=app.GetWorkbooks(); lpDisp = books.Open(m_filepath, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional ); //与的不同,是个参数的,直接在后面加了两个covOptional成功了 book.AttachDispatch(lpDisp); 3. 保存一个excel文件实例 [cpp] view plaincopy book.SetSaved(TRUE); 4. 另存一个excel文件实例 [cpp] view plaincopy book.SaveAs(COleVariant(m_filename),covOptional, covOptional,covOptional, covOptional,covOptional,(long)0, covOptional,covOptional,covOptional, covOptional,covOptional); //与的不同,是个参数的,直接在后面加了两个covOptional成功了 5. 释放一个excel文件实例 经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错) [cpp] view plaincopy //释放对象(相当重要!) Rang.ReleaseDispatch(); sheet.ReleaseDispatch(); sheets.ReleaseDispatch(); book.ReleaseDispatch(); books.ReleaseDispatch(); //退出程序 app.Quit(); //m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错 app.ReleaseDispatch(); 6. 修改一个excel单元格 [cpp] view plaincopy range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col))); range.SetValue2(COleVariant(value)); 7. 取出一个excel单元格 实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。 [cpp] view plaincopy range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col))); COleVariant rValue; rValue=COleVariant(range.GetValue2()); rValue.ChangeType(VT_BSTR); return CString(rValue.bstrVal); 8. 还有释放问题是最重要的问题: 首先变量必须全释放,无论当初是否绑定过; 其次,程序释放和程序关闭的顺序必须是 [cpp] view plaincopy app.Quit(); app.ReleaseDispatch(); 如果顺如颠倒如下: app.ReleaseDispatch(); app.Quit(); 出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。 附录(操作类源码): [cpp] view plaincopy #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: 初始化函数,初始化中附加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; } //在程序执行文件路径名中,剪掉执行文件名,得到程序路径,追加模板文件名,得到模板完整路径 } //////////////////////////////////////////////////////////////////////// ///Function: ~COptExcel ///Description: 析构函数,释放对象,非常重要,不全部释放,占用内存,下 /// 一次使用此类时会中断 ///Call: ReleaseDispatch() //////////////////////////////////////////////////////////////////////// COptExcel::~COptExcel(void) { books.ReleaseDispatch(); book.ReleaseDispatch(); sheets.ReleaseDispatch(); sheet.ReleaseDispatch(); range.ReleaseDispatch(); font.ReleaseDispatch(); cell.ReleaseDispatch(); 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) ) { AfxMessageBox(_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 ); //与office 2000的不同,是个参数的,直接在后面加了两个covOptional成功了 book.AttachDispatch(lpDisp); sheets=book.GetSheets(); sheet=sheets.GetItem(COleVariant((short)1)); //与的不同,是个参数的,直接在后面加了两个covOptional成功了 return true; } void COptExcel::NewExcelBook() { books=app.GetWorkbooks(); 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); } //////////////////////////////////////////////////////////////////////// ///Function: 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,covOptional,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(IndexToString(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() 从(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(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: IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串 ///Input: int col 要设置列宽的列 /// CString 宽值 //////////////////////////////////////////////////////////////////////// void COptExcel::SetColumnWidth(int col,CString width) { int row = 1; range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col))); range.SetColumnWidth(COleVariant(width)); } //////////////////////////////////////////////////////////////////////// ///Function: SetRowHeight ///Description: 设置行高 ///Call: IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串 ///Input: int row 单元格所在行 //////////////////////////////////////////////////////////////////////// CString COptExcel::GetColumnWidth(int col) { int row = 1; range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col))); VARIANT width = range.GetColumnWidth(); CString strwidth; strwidth.Format(CString((LPCSTR)(_bstr_t)(_variant_t)width)); return strwidth; } //////////////////////////////////////////////////////////////////////// ///Function: GetRowHeight ///Description: 设置行高 ///Call: IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串 ///Input: int row 要设置行高的行 /// CString 宽值 //////////////////////////////////////////////////////////////////////// CString COptExcel::GetRowHeight(int row) { int col = 1; range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col))); VARIANT height = range.GetRowHeight(); CString strheight; strheight.Format(CString((LPCSTR)(_bstr_t)(_variant_t)height)); return strheight; } //////////////////////////////////////////////////////////////////////// ///Function: IndexToString ///Description: 得到的单元格在EXCEL中的定位名称字符串 ///Input: int row 单元格所在行 /// int col 单元格所在列 ///Return: CString 单元格在EXCEL中的定位名称字符串 //////////////////////////////////////////////////////////////////////// CString COptExcel::IndexToString( int row, int col ) { CString strResult; if( col > 26 ) { strResult.Format(_T("%c%c%d"),'A' + (col-1)/26-1,'A' + (col-1)%26,row); } else { strResult.Format(_T("%c%d"), 'A' + (col-1)%26,row); } return strResult; } //////////////////////////////////////////////////////////////////////// ///Function: LastLineIndex ///Description: 得到表格总第一个空行的索引 ///Return: int 空行的索引号 //////////////////////////////////////////////////////////////////////// int COptExcel::LastLineIndex() { int i,j,flag=0; CString str; for(i=1;;i++) { flag = 0; //粗略统计,认为前列都没有数据即为空行 for(j=1;j<=5;j++) { str.Format(_T("%s"),this->GetCellValue(i,j).Trim()); if(str.Compare(_T(""))!=0) { flag = 1; break; } } if(flag==0) return i; } }
相关文章推荐
- C# 微信接口之推送模版消息
- NSIS 自定义安装界面准确获取安装进度完美解决方案
- 六大原则
- 多校第七场 1011 hdu 5379 Mahjong tree(树形dp)
- 编译FFMPEG错误对策
- 映射关系
- centos配置nfs服务详细步骤(centos开启nfs服务)
- 质数因子
- Mac OS 搭建phonegap开发环境
- bitmap格式分析(转)
- jQuery_统计图插件-XML/SWF Charts
- 数据结构实验之队列一:排队买饭
- phaser入门教程
- 如何在win7电脑系统中安装远程桌面控制台程序
- 合成复用原则
- 文章标题
- C#操作注册表
- canvas绘制简单小铅笔
- hbm2ddl
- GDB: don't know how to run