VC中调用 Excel 的总结

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();      
  }      
          添加完以上程序后,可运行看结果。      
     
   
   
  以上内容都是网络上搜到的,给了我很大的帮助,贴出来希望能给需要的朋友些帮助

posted @ 2009-06-30 11:13  dzqabc  阅读(3926)  评论(0编辑  收藏  举报