MFC中使用EXCEL2010方法

使用MFC操作EXCEL文件

一、加载

1、在VC6.0里创建一个MFC工程

2、打开MFC ClassWizard窗口(查看—>建立类向导),选择Automation,单击Add Class 按钮,选择From a type library...,弹出文件选择对话框,之后定位到C:\Program

Files\Microsoft Office\OFFICE11\EXCEL.EXE,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。

3、返回编辑器,查看工程文件,可发现多了EXCEL.H及EXCEL.CPP两个文件,拷贝出来,放在VS2005需要使用excel的工程文件中。

4. 打开stdafx.h头文件确保包含如下头文件:

#include (这个一般有了)

#include "excel.h" (手动添加这个即可)

5. 打开TestExcel.cpp文件,修改CTestExcelApp::InitInstance(),加入如下代码:

if( !AfxOleInit() ){

AfxMessageBox("初始化Ole出错!");

return FALSE;

}

为保证编译时不产生重复定义错误(可以验证一下是否成功加载,没有也能正常执行),我编译时出现了很多“类重复定义”异常,打开excel.h文件,在文件开始位置加入如下代码:

#if !defined _HEAD_FILE_EXCEL9_

#define _HEAD_FILE_EXCEL9_

相应的,在文件末尾加入:

#endif

成功

二、操作EXCEL文件

1. 新建一个excel表,并填充两个单元格的实例

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表格实例

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文件实例

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文件实例

经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错)

//释放对象(相当重要!)

Rang.ReleaseDispatch();

sheet.ReleaseDispatch();

sheets.ReleaseDispatch();

book.ReleaseDispatch();

books.ReleaseDispatch();

//退出程序

app.Quit();

//m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错app.ReleaseDispatch();

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,col))); 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表格。

附录(操作类源码):

#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(https://www.360docs.net/doc/d99489752.html,pare(_T(""))!=0)

{

flag = 1;

break;

}

}

if(flag==0)

return i;

}

}

相关文档
最新文档