CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

VC中调用 Excel 的总结(个人整理)

楼主38062708(土豆精)2006-03-09 09:38:40 在 VC/MFC / 基础类 提问

1、MSDN   上的代码,很好的例子  
   
  #include   "excel8.h"  
   
   
      //   OLE   Variant   for   Optional.  
              COleVariant   VOptional((long)DISP_E_PARAMNOTFOUND,   VT_ERROR);  
   
              _Application   objApp;  
              _Workbook   objBook;  
              Workbooks   objBooks;  
              Worksheets   objSheets;  
              _Worksheet   objSheet;  
              Range   objRange;  
              VARIANT   ret;  
   
              //   Instantiate   Excel   and   open   an   existing   workbook.  
              objApp.CreateDispatch("Excel.Application");  
              objBooks   =   objApp.GetWorkbooks();  
              objBook   =   objBooks.Open("C:\\Test.xls",  
                                  VOptional,   VOptional,   VOptional,   VOptional,  
                                  VOptional,   VOptional,   VOptional,   VOptional,  
                                  VOptional,   VOptional,   VOptional,   VOptional);  
              objSheets   =   objBook.GetWorksheets();  
              objSheet   =   objSheets.GetItem(COleVariant((short)1));  
   
              //Get   the   range   object   for   which   you   wish   to   retrieve   the  
              //data   and   then   retrieve   the   data   (as   a   variant   array,   ret).  
              objRange   =   objSheet.GetRange(COleVariant("A1"),   COleVariant("C8"));  
              ret   =   objRange.GetValue();  
   
              //Create   the   SAFEARRAY   from   the   VARIANT   ret.  
              COleSafeArray   sa(ret);  
   
              //Determine   the   array's   dimensions.  
              long   lNumRows;  
              long   lNumCols;  
              sa.GetUBound(1,   &lNumRows);  
              sa.GetUBound(2,   &lNumCols);  
   
              //Display   the   elements   in   the   SAFEARRAY.  
              long   index[2];  
              VARIANT   val;  
              int   r,   c;  
              TRACE("Contents   of   SafeArray\n");  
              TRACE("=====================\n\t");  
              for(c=1;c<=lNumCols;c++)  
              {  
                    TRACE("\t\tCol   %d",   c);  
              }  
              TRACE("\n");  
              for(r=1;r<=lNumRows;r++)  
              {  
                    TRACE("Row   %d",   r);  
                    for(c=1;c<=lNumCols;c++)  
                    {  
                          index[0]=r;  
                          index[1]=c;  
                          sa.GetElement(index,   &val);  
                          switch(val.vt)  
                          {  
                          case   VT_R8:  
                                {  
                                      TRACE("\t\t%1.2f",   val.dblVal);  
                                      break;  
                                }  
                          case   VT_BSTR:  
                                {  
                                      TRACE("\t\t%s",(CString)val.bstrVal);  
                                      break;  
                                }  
   
                          case   VT_EMPTY:  
                                {  
                                      TRACE("\t\t<empty>");  
                                      break;  
                                }  
                          }  
                    }  
                    TRACE("\n");  
              }  
   
              //Close   the   workbook   without   saving   changes  
              //and   quit   Microsoft   Excel.  
              objBook.Close(COleVariant((short)FALSE),   VOptional,   VOptional);  
              objApp.Quit();  
   
  待续...   ... 问题点数:20、回复次数:14Top

1 楼38062708(土豆精)回复于 2006-03-09 09:39:19 得分 0

 
  2、不错的一篇文章  
   
  在VC中彻底玩转Excel    
     
  作者:龚敏       来源:子玉山庄       更新:10/8/2004    
   
        如今Excel是越来越重要了,在我们自己开发的程序中不免要和Excel打交道了。利用Automation技术,我们可以在不去了解  
  数据库的情况下玩转Excel,而且你会发现一切竟如此轻松!  
          好了,咱们开始吧,我不喜欢用长篇累牍的代码来故弄玄虚,所以下面的代码都是切中要害的片段,总体上是个连贯的过程,  
  包括启动Excel,读取数据,写入数据,以及最后的关闭Excel,其中还包括了很多人感兴趣的合并单元格的处理。  
          特别说明以下代码需要MFC的支持,而且工程中还要包含EXCEL2000的定义文件:EXCEL9.H,EXCEL9.CPP  
   
  *****************************************************************************************************************  
   
    //*****  
    //变量定义  
    _Application   app;          
    Workbooks   books;  
    _Workbook   book;  
    Worksheets   sheets;  
    _Worksheet   sheet;  
    Range   range;  
    Range   iCell;  
    LPDISPATCH   lpDisp;          
    COleVariant   vResult;  
    COleVariant  
                  covTrue((short)TRUE),  
                  covFalse((short)FALSE),  
                  covOptional((long)DISP_E_PARAMNOTFOUND,   VT_ERROR);          
     
     
    //*****  
    //初始化COM的动态连接库  
    if(!AfxOleInit())      
    {  
                  AfxMessageBox("无法初始化COM的动态连接库!");  
                  return   ;  
            }        
     
     
    //*****  
    //创建Excel   2000服务器(启动Excel)  
    if(!app.CreateDispatch("Excel.Application"))    
    {  
      AfxMessageBox("无法启动Excel服务器!");  
          return;  
    }  
     
    app.SetVisible(TRUE);                     //使Excel可见  
    app.SetUserControl(TRUE);             //允许其它用户控制Excel  
     
   
    //*****        
    //打开c:\\1.xls  
    books.AttachDispatch(app.GetWorkbooks());  
    lpDisp   =   books.Open("C:\\\\1.xls",              
        covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
        covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
        covOptional,   covOptional   );          
       
             
    //*****  
    //得到Workbook  
    book.AttachDispatch(lpDisp);  
     
     
    //*****  
    //得到Worksheets    
    sheets.AttachDispatch(book.GetWorksheets());    
     
    #include   "excel8.h"  
   
   
   
    //*****  
    //得到当前活跃sheet  
    //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待  
    lpDisp=book.GetActiveSheet();  
    sheet.AttachDispatch(lpDisp);    
       
   
    //*****  
    //读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列  
    Range   usedRange;  
    usedRange.AttachDispatch(sheet.GetUsedRange());  
    range.AttachDispatch(usedRange.GetRows());  
    long   iRowNum=range.GetCount();                                       //已经使用的行数  
     
    range.AttachDispatch(usedRange.GetColumns());  
    long   iColNum=range.GetCount();                                       //已经使用的列数  
       
    long   iStartRow=usedRange.GetRow();                               //已使用区域的起始行,从1开始  
    long   iStartCol=usedRange.GetColumn();                         //已使用区域的起始列,从1开始  
       
       
    //*****  
    //读取第一个单元格的值  
    range.AttachDispatch(sheet.GetCells());    
    range.AttachDispatch(range.GetItem   (COleVariant((long)1),COleVariant((long)1)).pdispVal   );  
    COleVariant   vResult   =range.GetValue();  
    CString   str;  
    if(vResult.vt   ==   VT_BSTR)               //字符串  
    {  
      str=vResult.bstrVal;  
    }  
    else   if   (vResult.vt==VT_R8)           //8字节的数字    
    {  
      str.Format("%f",vResult.dblVal);  
    }  
    else   if(vResult.vt==VT_DATE)         //时间格式  
    {  
      SYSTEMTIME   st;  
            VariantTimeToSystemTime(&vResult.date,   &st);  
    }  
    else   if(vResult.vt==VT_EMPTY)       //单元格空的  
    {  
      str="";  
    }      
     
     
    //*****  
    //读取第一个单元格的对齐方式,数据类型:VT_I4  
    //读取水平对齐方式  
    range.AttachDispatch(sheet.GetCells());  
    iCell.AttachDispatch((range.GetItem   (COleVariant(long(1)),   COleVariant(long(1)))).pdispVal);  
    vResult.lVal=0;  
    vResult=iCell.GetHorizontalAlignment();  
    if(vResult.lVal!=0)  
    {  
      switch   (vResult.lVal)  
      {  
      case   1:             //默认  
        break;  
      case   -4108:     //居中  
        break;  
      case   -4131   :   //靠左  
        break;  
      case   -4152   :   //靠右  
        break;  
      }  
     
    }  
       
    //垂直对齐方式  
    iCell.AttachDispatch((range.GetItem   (COleVariant(long(1)),   COleVariant(long(1)))).pdispVal);  
    vResult.lVal=0;  
    vResult=iCell.GetVerticalAlignment();  
    if(vResult.lVal!=0)  
    {  
      switch   (vResult.lVal)  
      {  
      case   -4160   :     //靠上  
        break;  
      case   -4108   :     //居中  
        break;  
      case   -4107   :     //靠下  
        break;  
      }  
     
    }  
     
       
    //*****  
    //设置第一个单元格的值"HI,EXCEL!"  
    range.SetItem(COleVariant(1),COleVariant(1),COleVariant("HI,EXCEL!"));    
     
   
    //*****  
    //设置第一个单元格字体颜色:红色  
    Font   font;  
    range.AttachDispatch(sheet.GetCells());  
    range.AttachDispatch((range.GetItem   (COleVariant(long(1)),   COleVariant(long(1)))).pdispVal);  
    font.SetColor(COleVariant((long)0xFF0000));      
     
     
    //*****  
    //合并单元格的处理  
    //包括判断第一个单元格是否为合并单元格,以及将第一个单元格进行合并  
    Range   unionRange;  
    range.AttachDispatch(sheet.GetCells());    
    unionRange.AttachDispatch(range.GetItem   (COleVariant((long)1),COleVariant((long)1)).pdispVal   );  
       
    vResult=unionRange.GetMergeCells();          
    if(vResult.boolVal==-1)                           //是合并的单元格          
    {  
      //合并单元格的行数    
      range.AttachDispatch   (unionRange.GetRows   ());  
      long   iUnionRowNum=range.GetCount   ();    
         
      //合并单元格的列数  
      range.AttachDispatch   (unionRange.GetColumns   ());  
      long   iUnionColumnNum=range.GetCount   ();        
       
      //合并区域的起始行,列  
      long   iUnionStartRow=unionRange.GetRow();               //起始行,从1开始  
      long   iUnionStartCol=unionRange.GetColumn();         //起始列,从1开始  
       
    }  
    else   if(vResult.boolVal==0)        
    {//不是合并的单元格}  
     
    //将第一个单元格合并成2行,3列  
    range.AttachDispatch(sheet.GetCells());    
    unionRange.AttachDispatch(range.GetItem   (COleVariant((long)1),COleVariant((long)1)).pdispVal   );  
    unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)2),COleVariant((long)3)));  
    unionRange.Merge(COleVariant((long)0));       //合并单元格  
     
     
    //*****  
    //将文件保存为2.xls    
    book.SaveAs(COleVariant("C:\\\\2.xls"),covOptional,covOptional,   \\  
      covOptional,covOptional,covOptional,0,\\  
      covOptional,covOptional,covOptional,covOptional);      
       
       
    //*****  
    //关闭所有的book,退出Excel    
    book.Close   (covOptional,COleVariant(OutFilename),covOptional);  
    books.Close();              
    app.Quit();                    
     
  待续   ...   ...Top

2 楼38062708(土豆精)回复于 2006-03-09 09:39:50 得分 0

3、另一篇不错的文章  
   
  在Visual   C++   中调用Excel   2000    
  2001-06-14   19:02:39   程   蓬    
       
        在开发软件时,经常要将数据输出到Excel   2000中,在Excel   2000中对该数据进行进一步地格式化处理或进行计算处理。在Visual   Basic中处理起来较简单,Excel   2000的VB编程帮助中有较为详细的介绍。在Visual   C++中如何进行处理了?利用Excel   2000的ActiveX   Automate功能,处理起来同VB中类似。但要注意以下几点:      
  对于对象的属性值的读取或赋值,需要用GetProperty()或SetProperty(NewValue)函数,不能象VB中直接通过属性名称取值或赋值。例如:Worksheet.GetCount(),   Worksheet.SetName(“Sheet1”)。      
  对集合对象中的成员对象的引用,必须使用集合对象的GetItem()函数。例如:Worksheets.GetItem(ColeVariant((long)1))或Worksheets.GetItem(ColeVariant(“Sheet1”))取得第一个工作表。      
          在COM接口中,时常用到Variant,BSTR,SafeArray数据类型。Variant数据类型是一个联合,可表示几乎所有的类型的数据,具体用法见MSDN中的相关介绍,类_variant_t是对VARIANT数据类型的封装。在Excel   2000的VB编程帮助中,如果提到某函数或属性需要一个值,该值的数据类型通常是Variant,在封装Excel   2000对象的类定义中,说明了具体需要的数据类型。BSTR是一个包括了字符串和字符串长度的数据结构,类_bstr_t是对BSTR数据类型的封装。在Excel   2000的VB编程帮助中提到的字符串通常指BSTR。具体函数参数或属性的数据类型,见封装该对象的类的定义。SafeArray是一个包括数组和数组边界的结构,数组边界外的内容不允许访问。在Excel   2000的VB编程帮助中提到的数组是指SafeArray。关于SafeArray的处理,请见MSDN的相关帮助。      
          对于缺省参数和缺省值。在VB中,函数的参数可以空缺,在VC++中不允许,必须将所有的参数填写完全。如果你希望指定某个参数为缺省值,根据参数数据类型的不同,可指定不同的缺省值。当参数数据类型为字符串时,可以用长度为0的字符串。如果参数是Variant类型,可用常量vtMissing,该常量在comdef.h中定义。也可用_variant_t(DISP_E_PARAMNOTFOUND,   VT_ERROR)产生一个Variant对象。      
          Excel对象中的集合对象有时包括的子对象是不一定的,例如:Range对象,可以表示Cell的集合,也可以表示Column的集合或Row的集合,Range.GetItem(1)可以返回Cell或Column或Row对象。      
          对对象的引用或传递对象,使用IDispatch类对象,有时利用Variant对IDispatch进行包装。      
          以下是一段源程序,演示如何启动Excel   2000,利用一个模板文件产生一个新文档,在该文档的”Sheet1”工作表的第一个单元中填写一段文字,设置第一列的列宽,然后调用一个模板中的宏,执行一段程序,最后打印预览该Excel文档。模板文件名称:MyTemplate.xlt。程序在Visual   C++   6.0   sp4,Windows   2000   Professional   sp-1下调试通过。      
          首先利用Visual   C++   6.0,建立一个MFC基于对话框的工程项目,共享DLL,Win32平台。工程名称ExcelTest。在主对话框中加入一个按钮,      
  ID   IDC_EXCELTEST      
  Caption   Test   Excel      
  双击该按钮,增加成员函数void   CExcelTestDlg::OnExceltest()。      
  在BOOL   CExcelTestApp::InitInstance()中,dlg.DoModal();之前增加代码:      
  if   (CoInitialize(NULL)!=0)      
  {      
  AfxMessageBox("初始化COM支持库失败!");      
  exit(1);      
  }      
          在return   FALSE;   语句前,加入:CoUninitialize();      
          选择Menu->View->ClassWizade,打开ClassWizade窗口,选择Add   Class->From   a   type   library,选择D:\Program   Files\Microsoft   Office\office\Excel9.OLB(D:\Program   Files\Microsoft   Office\是本机上Microsoft   Office   2000的安装目录,可根据个人机器上的实际安装目录修改)。选择_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range,加入新类,分别为_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range,头文件Excel9.h,源文件Excel9.cpp。      
          在ExcelTestDlg.cpp文件的头部,#include   "ExcelTestDlg.h"语句之下,增加   :      
  #include   "comdef.h"      
  #include   "Excel9.h"      
          在void   CExcelTestDlg::OnExceltest()   函数中增加如下代码:      
  void   CExcelTestDlg::OnExceltest()        
  {      
  _Application   ExcelApp;      
  Workbooks   wbsMyBooks;      
  _Workbook   wbMyBook;      
  Worksheets   wssMysheets;      
  _Worksheet   wsMysheet;      
  Range   rgMyRge;      
  //创建Excel   2000服务器(启动Excel)      
       
  if   (!ExcelApp.CreateDispatch("Excel.Application",NULL))      
  {      
  AfxMessageBox("创建Excel服务失败!");      
  exit(1);      
  }      
  //利用模板文件建立新文档      
  wbsMyBooks.AttachDispatch(ExcelApp.GetWorkbooks(),true);      
  wbMyBook.AttachDispatch(wbsMyBooks.Add(_variant_t("g:\\exceltest\\MyTemplate.xlt")));      
  //得到Worksheets      
  wssMysheets.AttachDispatch(wbMyBook.GetWorksheets(),true);      
  //得到sheet1      
  wsMysheet.AttachDispatch(wssMysheets.GetItem(_variant_t("sheet1")),true);      
  //得到全部Cells,此时,rgMyRge是cells的集合      
  rgMyRge.AttachDispatch(wsMysheet.GetCells(),true);      
  //设置1行1列的单元的值      
  rgMyRge.SetItem(_variant_t((long)1),_variant_t((long)1),_variant_t("This   Is   A   Excel   Test   Program!"));      
  //得到所有的列      
  rgMyRge.AttachDispatch(wsMysheet.GetColumns(),true);      
  //得到第一列      
  rgMyRge.AttachDispatch(rgMyRge.GetItem(_variant_t((long)1),vtMissing).pdispVal,true);      
  //设置列宽      
  rgMyRge.SetColumnWidth(_variant_t((long)200));      
  //调用模板中预先存放的宏      
  ExcelApp.Run(_variant_t("CopyRow"),_variant_t((long)10),vtMissing,vtMissing,      
  vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,      
  vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,      
  vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,      
  vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing);      
  //打印预览      
  wbMyBook.SetSaved(true);      
  ExcelApp.SetVisible(true);      
  wbMyBook.PrintPreview(_variant_t(false));      
  //释放对象      
  rgMyRge.ReleaseDispatch();      
  wsMysheet.ReleaseDispatch();      
  wssMysheets.ReleaseDispatch();      
  wbMyBook.ReleaseDispatch();      
  wbsMyBooks.ReleaseDispatch();      
  ExcelApp.ReleaseDispatch();      
  }      
          添加完以上程序后,可运行看结果。      
     
   
   
  以上内容都是网络上搜到的,给了我很大的帮助,贴出来希望能给需要的朋友些帮助Top

3 楼xx_jj()回复于 2006-03-09 10:23:28 得分 20

楼主是好人÷÷     祝福Top

4 楼Snow_Ice11111(雪上加冰)回复于 2006-03-09 10:53:39 得分 0

Thanks   a   lot!!It's   very   useful   to   me!Top

5 楼Atomictry(天影)回复于 2006-03-09 11:06:05 得分 0

建议:   Excel有多种读写方法,你可以在这里再总结一下各种方法的优劣。Top

6 楼kugou123(酷狗)(彪悍的人生,不需要解释 www.xiaozhou.net)回复于 2006-03-09 11:20:24 得分 0

VCKBASE有篇通过分析EXCEL格式,直接构造EXCEL文件的文章,也不错的。楼主可以去看看。Top

7 楼38062708(土豆精)回复于 2006-03-09 11:38:21 得分 0

多谢大家支持,上面三篇文章是我在写程序时用到的,尤其是第一篇,来自MSDN,对我帮助很大Top

8 楼lynx090(黑色的风)回复于 2006-03-09 12:42:12 得分 0

我想问问,客户的EXCEL的版本不同的呀,怎么包含头文件?Top

9 楼Windforce_328(阿蒙)回复于 2006-03-09 14:15:41 得分 0

楼主知道怎么设置页眉页脚吗?因为有的内容是根据即时情况显示的,所以不能在模板中写死.Top

10 楼Windforce_328(阿蒙)回复于 2006-03-09 14:23:59 得分 0

比如说在打印的时候需在页眉处打印进行打印操作的用户名,怎么处理?Top

11 楼cody_wuhui(※*Ace*※)回复于 2006-03-09 23:24:44 得分 0

支持!谢谢分享!Top

12 楼soft78(我爱VC)回复于 2006-03-09 23:39:18 得分 0

请问在退出Excel打印预览后不用点X而自动关闭Excel?Top

13 楼gold_water(风雨无阻)回复于 2006-03-10 09:00:23 得分 0

好人啦!!!!Top

14 楼iloveyzgw1029(深白色)回复于 2006-03-15 10:47:37 得分 0

啥也不说了,楼主是活雷锋!Top

相关问题

  • VC调用EXCEL的问题
  • VC中调用EXCEL画图JI
  • 如何在VC中调用excel对象?
  • 如何用非MFC的VC调用EXCEL?
  • vc调用excel能否不要用到excel模板?
  • VC调用EXCEL,如何去掉EXCEL的菜单?
  • 高手Help me! VC调用Excel时如何设置Open()方法!
  • vc调用excel的问题,请各位朋友捧场!
  • vc中调用excel中出现的问题,请求帮助。
  • 请教各位:VC中调用Excel的问题?

关键词

  • visual c++
  • excel
  • 代码
  • application
  • voptional
  • objbook
  • objsheet
  • colevariant
  • objapp
  • workbooks

得分解答快速导航

  • 帖主:38062708
  • xx_jj

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo