VC编程操作Excel
2017-07-10 17:42
253 查看
1. 在VC6上验证通过!
建立VC工程,本章说明一般是针对MFC
2.
加入Excel的库文件.
从classwizard中add class处from type library,去office的安装目录下引入excel.exe(这是office 2003的选择,其他版本都是用olb文件),服务器就算引入了,这时会弹出对话框,要求加入一些类,这些类都是一些接口,里面有大量的方法,类的对象表征着excel文件的一个个部分,加载库后会自动生成相应的接口头文件和源文件
Excel的对象模型
Application:代表应用程序本身。即Excel应用程序
Workbooks:是Workbook 的集合,代表了工作薄。
Worksheets:是Worksheet的集合,是Workbook的子对象。
Range:是Worksheet的子对象,可以理解为Sheet中一定范围的单元格。
Shapes:是Worksheet的子对象,用于存储图片等信息的单元格
3.
初始化COM库.
在app的Initstance函数中添加始化代码:
4.
不过在控制台程序中调用AfxOleInit()是无效的;
然后,创建Excel 服务器(启动Excel)
定义app的全局或成员变量
设置Excel的状态:
5.
VC对Excel的操作
定义变量
6.
打开已有的Excel文件
7.
新建一个.xls文件,并写入数据
8.
合并单元格
9.
向单元格中插入图片(支持BMP、JPG格式,其他没试)
10.
将已建的.xls文件另存为
11.
关闭Excel服务
一、加载
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 <afxdisp.h>(这个一般有了)
#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
成功
在MSDN中,很少有excel方面的资料,但是在http://msdn.microsoft.com/zh-cn/ms348103.aspx中可以找到C#控制EXCEL方面的说明
二、操作EXCEL文件
1. 新建一个excel表,并填充两个单元格的实例
[cpp] view
plain copy
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
plain copy
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
plain copy
book.SetSaved(TRUE);
4. 另存一个excel文件实例
[cpp] view
plain copy
book.SaveAs(COleVariant(m_filename),covOptional,
covOptional,covOptional,
covOptional,covOptional,(long)0,
covOptional,covOptional,covOptional,
covOptional,covOptional); //与的不同,是个参数的,直接在后面加了两个covOptional成功了
5. 释放一个excel文件实例
经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错)
[cpp] view
plain copy
//释放对象(相当重要!)
Rang.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
//退出程序
app.Quit();
//m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
app.ReleaseDispatch();
6. 修改一个excel单元格
[cpp] view
plain copy
range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));
range.SetValue2(COleVariant(value));
7. 取出一个excel单元格
实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。
[cpp] view
plain copy
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
plain copy
app.Quit();
app.ReleaseDispatch();
如果顺如颠倒如下:
app.ReleaseDispatch();
app.Quit();
出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。
建立VC工程,本章说明一般是针对MFC
2.
加入Excel的库文件.
从classwizard中add class处from type library,去office的安装目录下引入excel.exe(这是office 2003的选择,其他版本都是用olb文件),服务器就算引入了,这时会弹出对话框,要求加入一些类,这些类都是一些接口,里面有大量的方法,类的对象表征着excel文件的一个个部分,加载库后会自动生成相应的接口头文件和源文件
Excel的对象模型
Application:代表应用程序本身。即Excel应用程序
Workbooks:是Workbook 的集合,代表了工作薄。
Worksheets:是Worksheet的集合,是Workbook的子对象。
Range:是Worksheet的子对象,可以理解为Sheet中一定范围的单元格。
Shapes:是Worksheet的子对象,用于存储图片等信息的单元格
3.
初始化COM库.
在app的Initstance函数中添加始化代码:
4.
if(!AfxOleInit()) { AfxMessageBox("无法初始化COM的动态连接库!"); return FALSE; }
不过在控制台程序中调用AfxOleInit()是无效的;
然后,创建Excel 服务器(启动Excel)
定义app的全局或成员变量
_Application app; if (!app.CreateDispatch("Excel.Application")) { AfxMessageBox("无法启动Excel服务器"); return FALSE; }
设置Excel的状态:
5.
app.SetVisible(bVisble); // 使Excel可见 app.SetUserControl(bControl); // 允许其他用户控制Excel
VC对Excel的操作
定义变量
Workbooks books; _Workbook book; Worksheets sheets; _Worksheet sheet; LPDISPATCH lpDisp; Range range; COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
6.
打开已有的Excel文件
books.AttachDispatch(app.GetWorkbooks()); // 或者也可以 // books = app.GetWorkbooks(); lpDisp = books.Open("", covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional);
7.
新建一个.xls文件,并写入数据
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); // Get the Workbooks collection so that you can add a new workbook books.AttachDispatch(app.GetWorkbooks()); // 得到Workbooks book = books.Add(covOptional); // 得到Workbook // Get the Worksheets collection so that you can get the IDispatch for the first Worksheet sheets = book.GetWorksheets(); // 得到Worksheets sheet = sheets.GetItem(COleVariant((short)1)); // 得到Worksheet // 分别向每个单元格添加数据 // Excel2000 用函数SetValue()即可, Excel2003用函数SetValue2() // range = sheet.GetRange(COleVariant("A1"), covOptional); // 获取A1 Range range.SetValue2( COleVariant("Date")); // 添加数据 range = sheet.GetRange(COleVariant("B1"), covOptional); // 获取B1 Range range.SetValue2(COleVariant("Order")); // 添加数据 range = sheet.GetRange(COleVariant("C1"), covOptional); // 获取C1 Range range.SetValue2(COleVariant("Amount")); // 添加数据 range = sheet.GetRange(COleVariant("D1"), covOptional); // 获取D1 Range range.SetValue2(COleVariant("Tax")); // 添加数据 // 向单元格中添加公式 range = sheet.GetRange(COleVariant("D2"), covOptional); // 获得D2 Range range = range.GetResize(COleVariant((long)NUMROWS), COleVariant((long)1)); // 重新设置D2的大小 range.SetFormula(COleVariant("=C2*0.07")); // 给D2:D21设置公式 // 设置单元格的格式 range = sheet.GetRange(COleVariant("A1"), COleVariant("D1")); // 获得A1:D1的Range oFont = range.GetFont(); // 获得Range的字体 oFont.SetBold(COleVariant((short)TRUE)); // 设置是否粗体 oFont.SetColor(COleVariant((long)RGB(255, 0, 0))); // 设置字体颜色 oFont.SetName(COleVariant("黑体")); // 设置字体类型 rang.SetNumberFormatLocal(COleVariant("@")); //设置单元格为文本,赋值前有效 range = range.GetEntireColumn(); // 获得全部的单元格 range.AutoFit(); // 自动适合尺寸
8.
合并单元格
// 思路:1.先获取A1:C1的Range范围,然后重新定义此范围,最后合并 // 2.直接获得A1:C2的Range范围,直接合并。结果和第一种方法一样 Range unionRange; unionRange = sheet.GetRange(COleVariant("A1"), COleVariant("C1")); vResult = unionRange.GetMergeCells(); unionRange = unionRange.GetResize(COleVariant((long)2), COleVariant((long)3)); unionRange.Merge(COleVariant((long)0)); //合并单元格 unionRange.SetRowHeight(COleVariant((short)30)); //设置单元格的高度 unionRange.SetHorizontalAlignment(COleVariant((long)-4108));// 水平居中对齐
9.
向单元格中插入图片(支持BMP、JPG格式,其他没试)
Shapes shapes = sheet.GetShapes(); // 从Sheet对象上获得一个Shapes range = sheet.GetRange(COleVariant("B16"),COleVariant("J22")); // 获得Range对象,用来插入图片 rgMyRge1 = range; shapes.AddPicture("D://Test1.jpg" , false , true , (float)range .GetLeft().dblVal, (float)range .GetTop().dblVal, // 从本地添加一个图片 (float)range .GetWidth().dblVal, (float)range .GetHeight().dblVal); ShapeRange sRange = shapes.GetRange(_variant_t(long(1))); sRange.SetHeight(float(30)); sRange.SetWidth(float(30));
10.
将已建的.xls文件另存为
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); book.SaveAs(COleVariant("D://3.xls"),covOptional,covOptional, covOptional,covOptional,covOptional,0, covOptional,covOptional,covOptional,covOptional,covOptional);
11.
关闭Excel服务
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); book.SetSaved(TRUE); // 将Workbook的保存状态设置为已保存,即不让系统提示是否人工保存 range.ReleaseDispatch(); // 释放Range对象 sheet.ReleaseDispatch(); // 释放Sheet对象 sheets.ReleaseDispatch(); // 释放Sheets对象 book.ReleaseDispatch(); // 释放Workbook对象 books.ReleaseDispatch(); // 释放Workbooks对象 book.Close (covOptional, covOptional,covOptional);// 关闭Workbook对象 books.Close(); // 关闭Workbooks对象 app.Quit(); // 退出_Application app.ReleaseDispatch (); // 释放_Application
一、加载
1、 在VC6.0里创建一个MFC工程
2、打开MFCClassWizard窗口(查看—>建立类向导),选择Automation,单击AddClass按钮,选择Froma type library...,弹出文件选择对话框,之后定位到C:\Program Files\MicrosoftOffice\OFFICE11\EXCEL.EXE,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。
4. 打开stdafx.h头文件确保包含如下头文件:
#include <afxdisp.h>(这个一般有了)
#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接口 | 导入类 | 头文件 | 说明 |
_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 | 一定数量的单元格,可对单元格进行单个或多个单元格进行操作。 |
二、操作EXCEL文件
1. 新建一个excel表,并填充两个单元格的实例
[cpp] view
plain copy
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
plain copy
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
plain copy
book.SetSaved(TRUE);
4. 另存一个excel文件实例
[cpp] view
plain copy
book.SaveAs(COleVariant(m_filename),covOptional,
covOptional,covOptional,
covOptional,covOptional,(long)0,
covOptional,covOptional,covOptional,
covOptional,covOptional); //与的不同,是个参数的,直接在后面加了两个covOptional成功了
5. 释放一个excel文件实例
经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错)
[cpp] view
plain copy
//释放对象(相当重要!)
Rang.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
//退出程序
app.Quit();
//m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
app.ReleaseDispatch();
6. 修改一个excel单元格
[cpp] view
plain copy
range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));
range.SetValue2(COleVariant(value));
7. 取出一个excel单元格
实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。
[cpp] view
plain copy
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
plain copy
app.Quit();
app.ReleaseDispatch();
如果顺如颠倒如下:
app.ReleaseDispatch();
app.Quit();
出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。
相关文章推荐
- VC编程操作Excel
- VC操作EXCEL
- ASP编程操作Excel(提高版)
- VC++与Matlab混合编程之引擎操作详解
- (转)VC数字图像处理编程讲座之三 ---BMP图像的基本操作
- Visual C# 编程操作Excel
- Visual C# 编程操作Excel
- 针对Excel表格文件操作的编程实现
- vc编程使excel的关闭按钮失效的方法
- [导入]C# 编程操作Excel
- Visual C# 编程操作Excel
- 针对Excel表格文件操作的编程实现
- vc知识积累(2.操作Excel数据库)
- 针对Excel表格文件操作的编程实现
- vc操作excel程序退出的问题
- 运用VC或Java对Office进行编程操作
- Visual C# 编程操作Excel
- VC操作EXCEL(1)
- VC操作XML编程实例
- 运用VC或Java对Office进行编程操作