VC操作Excel(总结)

1.

#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();  

*****************************************************************************************************************

 

2.

[原创]在VC中彻底玩转Excel
    如今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()); 
 
 
 //*****
 //得到当前活跃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();         
 


*****************************************************************************************************************

3.

       在开发软件时,经常要将数据输出到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();      
  }      

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【前言】 工作或学习中可能需要实现基于VC读\写Excel文件的功能,本人最近也遇到了该问题。中间虽经波折,但是最终还是找到了解决问题的办法。 在此跟大家分享,希望对跟我同样迷茫过的同学们有所帮助。 1、程序功能 1)打开一个excel文件; 2)显示到CListCtrl上; 3)新建一个Excel文件。 以上均在对话框中实现。 2、平台 VC++2010 3、实现方法 常用的Excel打开方式有两种 1)通过数据库打开; 2)OLE方式打开。 由于方式1)操作繁琐,经常出现莫名的错误,这里选用方式2). 4、准备步骤 首先新建一个Dialog窗体程序,添加list control和两个按钮 1)将ExcelLib文件夹拷贝到程序目录下; 2)将Export2Excel.h,Export2Excel.cpp两个文件添加到项目; 3)包含头文件,#include "ExcelLib/Export2Excel.h" 通过以上步骤在程序中引入了可以读取Excle文件的CExport2Excel类; 5、打开excel文件 通过按钮点击打开 void CExcelTestDlg::OnBnClickedButtonOpenExcel() { //获取文件路径 CFileDialog* lpszOpenFile; CString szGetName; lpszOpenFile = new CFileDialog(TRUE,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"Excel File(*.xlsx;*.xls)|*.xls;*.xlsx",NULL); if (lpszOpenFile->DoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //打开文件 //文件中包含多个sheet时,默认打开第一个sheet CExport2Excel Excel_example; Excel_example.OpenExcel(szGetName); //获取sheet个数 int iSheetNum = Excel_example.GetSheetsNumber(); //获取已使用表格行列数 int iRows = Excel_example.GetRowCount(); int iCols = Excel_example.GetColCount(); //获取单元格的内容 CString cs_temp = Excel_example.GetText(1,1); //AfxMessageBox(cs_temp); //List control上显示 //获取工作表列名(第一行) CStringArray m_HeadName; m_HeadName.Add(_T("ID")); for (int i=1;iGetItemCount()>0) { m_list.DeleteColumn(0); } //初始化ClistCtrl,加入列名 InitList(m_list,m_HeadName); //填入内容 //第一行是标题,所以从第2行开始 CString num; int pos; for (int row = 2;row<=iRows; row++) { pos = m_list.GetItemCount(); num.Format(_T("%d"),pos +1); m_list.InsertItem(pos,num); for (int colum=1;columDoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //文件全名称 CString csFileName = szGetName; //需要添加的两个sheet的名称 CString csSheetName = "newSheet"; CString csSheetName2 = "newSheet2"; // 新建一个excel文件,自己写入文字 CExport2Excel Excel_example; //新建excel文件 Excel_example.CreateExcel(csFileName); //添加sheet,新加的sheet在前,也就是序号为1 Excel_example.CreateSheet(csSheetName); Excel_example.CreateSheet(csSheetName2); //操作最开始添加的sheet:(newSheet) Excel_example.SetSheet(2); //添加表头 Excel_example.WriteHeader(1,"第一列"); Excel_example.WriteHeader(2,"第二列"); //添加核心数据 Excel_example.WriteData(1,1,"数据1"); Excel_example.WriteData(1,2,"数据2"); //保存文件 Excel_example.Save(); //关闭文件 Excel_example.Close(); } 7、注意事项 1)一般单个Excel文件包含多个sheet,程序默认打开第一个; 2)指定操作sheet,使用Excel_example.SetSheet(2)函数; 3)打开文件时最左侧的sheet序号为1,新建excel时最新添加的sheet序号为1. 【后记】 本程序主要基于网络CSDN中---“Excel封装库V2.0”---完成,下载地址是:http://download.csdn.net/detail/yeah2000/3576494,在此表示感谢!同时, 1)在其基础上作了小改动,改正了几个小错误,添加了几个小接口; 2)添加了如何使用的例子,原程序是没有的; 3)详细的注释 发现不足之处,还请大家多多指教!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值