VC编程操作Excel

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.

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,在生成类中添加所有的对象(其实添加需要的即可,为了简便,不出错保留了冗余),如下图。



 
 

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

成功

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表,并填充两个单元格的实例

[cpp]  view plain  copy
  1. void CTestExcelDlg::OnButton1()  
  2. {  
  3. //Workbooks—>Workbook —>Worksheets—>Worksheet —>Range  
  4. _Application app;       //Excel应用程序接口  
  5. Workbooks books;        //工作薄集合  
  6. _Workbook book;     //工作薄  
  7. Worksheets sheets;      //工作表集合  
  8. _Worksheet sheet;       //工作表  
  9. Range range;            //Excel中针对单元格的操作都应先获取其对应的Range对象  
  10. Font font;  
  11. Range cols;  
  12. /* 
  13. COleVariant类为VARIANT数据类型的包装,在自动化程序中,通常都使用 
  14. VARIANT数据类型进行参数传递。故下列程序中,函数参数都是通过COleVariant 
  15. 类来转换了的。 
  16. */  
  17. //covOptional 可选参数的VARIANT类型  
  18. COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
  19. if( !app.CreateDispatch("Excel.Application") ){  
  20. this->MessageBox("无法创建Excel应用!");  
  21. return;  
  22. }  
  23. //获取工作薄集合  
  24. books=app.GetWorkbooks();  
  25. //添加一个工作薄  
  26. book=books.Add(covOptional);  
  27. //获取工作表集合  
  28. sheets=book.GetSheets();  
  29. //获取第一个工作表  
  30. sheet=sheets.GetItem(COleVariant((short)1));  
  31. //选择工作表中A1:A1单元格区域  
  32. range=sheet.GetRange(COleVariant("A1"),COleVariant("A1"));  
  33. //设置A1=HELLO EXCEL!"  
  34. range.SetValue(COleVariant("HELLO EXCEL!"));  
  35. //调整格式,设置粗体  
  36. font=range.GetFont();  
  37. font.SetBold(COleVariant((short)TRUE));  
  38. //选择A2单元格,插入一个公式"=RAND()*100000",并设置A2数字格式为货币形  
  39. 式  
  40. range=sheet.GetRange(COleVariant("A2"),COleVariant("A2"));  
  41. range.SetFormula(COleVariant("=RAND()*100000"));  
  42. range.SetNumberFormat(COleVariant("$0.00"));  
  43. //选择A:A列,设置宽度为自动适应  
  44. cols=range.GetEntireColumn();  
  45. cols.AutoFit();  
  46. //显示Excel表格,并设置状态为用户可控制  
  47. app.SetVisible(TRUE);  
  48. app.SetUserControl(TRUE);  

2. 打开一个已有的excel表格实例

[cpp]  view plain  copy
  1. CString strPath;   
  2. strPath += "C:\\template.xlt"// 模板的路径   
  3. CFileFind filefind;   
  4. if( !filefind.FindFile( strPath ) )   
  5. {   
  6. AfxMessageBox( "没有找到模版文档,请其查找" );   
  7.     return;  
  8. }   
  9. LPDISPATCH lpDisp;  //接口指针  
  10. books=app.GetWorkbooks();  
  11. lpDisp = books.Open(m_filepath,  
  12.     covOptional, covOptional, covOptional, covOptional,  
  13.     covOptional, covOptional, covOptional, covOptional,  
  14.     covOptional, covOptional, covOptional, covOptional,  
  15.     covOptional, covOptional  
  16.     );                  //与的不同,是个参数的,直接在后面加了两个covOptional成功了  
  17. book.AttachDispatch(lpDisp);  

3. 保存一个excel文件实例


[cpp]  view plain  copy
  1. book.SetSaved(TRUE);  

4. 另存一个excel文件实例

[cpp]  view plain  copy
  1. book.SaveAs(COleVariant(m_filename),covOptional,  
  2.     covOptional,covOptional,  
  3.     covOptional,covOptional,(long)0,  
  4. covOptional,covOptional,covOptional,  
  5. covOptional,covOptional); //与的不同,是个参数的,直接在后面加了两个covOptional成功了  

5. 释放一个excel文件实例

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

[cpp]  view plain  copy
  1. //释放对象(相当重要!)   
  2. Rang.ReleaseDispatch();   
  3. sheet.ReleaseDispatch();   
  4. sheets.ReleaseDispatch();   
  5. book.ReleaseDispatch();   
  6. books.ReleaseDispatch();   
  7. //退出程序   
  8. app.Quit();  
  9. //m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错   
  10. app.ReleaseDispatch();   

6. 修改一个excel单元格

[cpp]  view plain  copy
  1. range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
  2. range.SetValue2(COleVariant(value));  

7. 取出一个excel单元格

实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。

[cpp]  view plain  copy
  1. range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  
  2. COleVariant rValue;  
  3. rValue=COleVariant(range.GetValue2());  
  4. rValue.ChangeType(VT_BSTR);  
  5. return CString(rValue.bstrVal);  

8. 还有释放问题是最重要的问题:

   首先变量必须全释放,无论当初是否绑定过;

   其次,程序释放和程序关闭的顺序必须是

[cpp]  view plain  copy
  1. app.Quit();  
  2. app.ReleaseDispatch();  
  3. 如果顺如颠倒如下:  
  4. app.ReleaseDispatch();  
  5. app.Quit();  
  6. 出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。  

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值