在VC中彻底玩转Excel

本文介绍如何使用MFC和COM技术实现Excel的自动化编程,包括启动Excel、读取数据、写入数据、关闭Excel等基本操作,并详细展示了如何处理单元格的合并及字体颜色设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如今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();
  
*****************************************************************************************************************

                       作者 :龚敏
                       Email : unionsoft@163.com
                       主页 :http://www.szty.com.cn/gmsoft
                                 2003.10

unionsoft




Score: 173
Posts: 112
Posted on 2003-11-27 12:39  User profile  Search all posts by  Select and copy to clipboard. 
IE only, sorry for Netscape users:-)
修改字体颜色的那段漏了一句,应为:
//*****
  //设置第一个单元格字体颜色:红色
  Font font;
  range.AttachDispatch(sheet.GetCells());
  range.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);
  font.AttachDispatch (range.GetFont ());
  font.SetColor(COleVariant((long)0xFF0000));

george


Moderator

Score: 958
Posts: 617
Posted on 2004-01-08 13:51  User profile  Search all posts by  Select and copy to clipboard. 
IE only, sorry for Netscape users:-)
特别说明以下代码需要MFC的支持,而且工程中还要包含EXCEL2000的定义文件:EXCEL9.H,EXCEL9.CPP。

这两个文件在哪里呀?



枝上柳绵吹又少,天涯何处无芳草
unionsoft




Score: 173
Posts: 112
Posted on 2004-01-31 11:25  User profile  Search all posts by  Select and copy to clipboard. 
IE only, sorry for Netscape users:-)
george wrote:
特别说明以下代码需要MFC的支持,而且工程中还要包含EXCEL2000的定义文件:EXCEL9.H,EXCEL9.CPP。

这两个文件在哪里呀?


这两个文件可以从相应的类型库文件中提取,类型库文件位于office的安装目录下,你也可以搜索一下,具体名称如下:
Excel 95 and prior : xl5en32.olb
Excel 97 : excel8.olb
Excel 2000 : excel9.olb
Excel 2002 : excel.exe

提取方法:
在VC的MFC ClassWizard对话框中点击"Add Class..."按钮,选择"From a type libray...",找到相应的类型库即可
yhthy




Score: 483
Posts: 120
Posted on 2004-03-16 10:10  User profile  OICQ UIN: 31416801  Search all posts by  Select and copy to clipboard. 
IE only, sorry for Netscape users:-)
请问,如何新建一个book 以及新建一个sheet.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值