使用MFC操作EXCEL文件

来源:互联网 发布:linux移动文件命令 编辑:程序博客网 时间:2024/05/21 00:20

使用MFC操作EXCEL文件
分类: EXCEL 2012-09-03 09:30 14914人阅读 评论(5) 收藏 举报
excelmfcbooks工作applicationoffice
一、加载
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

include “excel.h” (手动添加这个即可)

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

void CTestExcelDlg::OnButton1()  {  //Workbooks—>Workbook —>Worksheets—>Worksheet —>Range  _Application app;       //Excel应用程序接口  Workbooks books;        //工作薄集合  _Workbook book;     //工作薄  Worksheets sheets;      //工作表集合  _Worksheet sheet;       //工作表  Range range;            //Excel中针对单元格的操作都应先获取其对应的Range对象  Font font;  Range cols;  /* COleVariant类为VARIANT数据类型的包装,在自动化程序中,通常都使用 VARIANT数据类型进行参数传递。故下列程序中,函数参数都是通过COleVariant 类来转换了的。 */  //covOptional 可选参数的VARIANT类型  COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  if( !app.CreateDispatch("Excel.Application") ){  this->MessageBox("无法创建Excel应用!");  return;  }  //获取工作薄集合  books=app.GetWorkbooks();  //添加一个工作薄  book=books.Add(covOptional);  //获取工作表集合  sheets=book.GetSheets();  //获取第一个工作表  sheet=sheets.GetItem(COleVariant((short)1));  //选择工作表中A1:A1单元格区域  range=sheet.GetRange(COleVariant("A1"),COleVariant("A1"));  //设置A1=HELLO EXCEL!"  range.SetValue(COleVariant("HELLO EXCEL!"));  //调整格式,设置粗体  font=range.GetFont();  font.SetBold(COleVariant((short)TRUE));  //选择A2单元格,插入一个公式"=RAND()*100000",并设置A2数字格式为货币形  式  range=sheet.GetRange(COleVariant("A2"),COleVariant("A2"));  range.SetFormula(COleVariant("=RAND()*100000"));  range.SetNumberFormat(COleVariant("$0.00"));  //选择A:A列,设置宽度为自动适应  cols=range.GetEntireColumn();  cols.AutoFit();  //显示Excel表格,并设置状态为用户可控制  app.SetVisible(TRUE);  app.SetUserControl(TRUE);  2. 打开一个已有的excel表格实例[cpp] view plaincopyCString strPath;   strPath += "C:\\template.xlt"; // 模板的路径   CFileFind filefind;   if( !filefind.FindFile( strPath ) )   {   AfxMessageBox( "没有找到模版文档,请其查找" );       return;  }   LPDISPATCH lpDisp;  //接口指针  books=app.GetWorkbooks();  lpDisp = books.Open(m_filepath,      covOptional, covOptional, covOptional, covOptional,      covOptional, covOptional, covOptional, covOptional,      covOptional, covOptional, covOptional, covOptional,      covOptional, covOptional      );                  //与的不同,是个参数的,直接在后面加了两个covOptional成功了  book.AttachDispatch(lpDisp);  3. 保存一个excel文件实例[cpp] view plaincopybook.SetSaved(TRUE);  4. 另存一个excel文件实例[cpp] view plaincopybook.SaveAs(COleVariant(m_filename),covOptional,      covOptional,covOptional,      covOptional,covOptional,(long)0,  covOptional,covOptional,covOptional,  covOptional,covOptional); //与的不同,是个参数的,直接在后面加了两个covOptional成功了  5. 释放一个excel文件实例经试验证实,不释放第二次使用excel时会中断,放在类的析构里面有时调用不到,主动调用最保险。(有没有AttachDispatch()过都要释放,否则报错)[cpp] view plaincopy//释放对象(相当重要!)   Rang.ReleaseDispatch();   sheet.ReleaseDispatch();   sheets.ReleaseDispatch();   book.ReleaseDispatch();   books.ReleaseDispatch();   //退出程序   app.Quit();  //m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错   app.ReleaseDispatch();   6. 修改一个excel单元格[cpp] view plaincopyrange=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  range.SetValue2(COleVariant(value));  7. 取出一个excel单元格实现Variant数据类型转换为CString类,这个只是一个示例,转换较为简单。[cpp] view plaincopyrange=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));  COleVariant rValue;  rValue=COleVariant(range.GetValue2());  rValue.ChangeType(VT_BSTR);  return CString(rValue.bstrVal);  8. 还有释放问题是最重要的问题:   首先变量必须全释放,无论当初是否绑定过;   其次,程序释放和程序关闭的顺序必须是[cpp] view plaincopyapp.Quit();  app.ReleaseDispatch();  如果顺如颠倒如下:  app.ReleaseDispatch();  app.Quit();  出现的后果是程序关闭后,excel进程仍然运行,所以无法正常打开程序曾经打开excel表格。  附录(操作类源码):[cpp] view plaincopy#include "../Stdafx.h"  #include "OptExcel.h"  #include "excel.h"  #include "comdef.h"  _Application app;  Workbooks books;  _Workbook book;  Worksheets sheets;  _Worksheet sheet;  Range range;  Range cell;  Font font;  COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  ////////////////////////////////////////////////////////////////////////  ///Function:    COptExcel  ///Description: 初始化函数,初始化中附加excel应用程序  ///Call:        app.CreateDispatch(_T("Excel.Application")  ////////////////////////////////////////////////////////////////////////  COptExcel::COptExcel(void)  {      if (::CoInitialize( NULL ) == E_INVALIDARG)       {           AfxMessageBox(_T("初始化Com失败!"));           return;      }      //验证office文件是否可以正确运行      if( !app.CreateDispatch(_T("Excel.Application")) )      {          AfxMessageBox(_T("无法创建Excel应用!"));          return;      }      //在程序执行文件路径名中,剪掉执行文件名,得到程序路径,追加模板文件名,得到模板完整路径  }  ////////////////////////////////////////////////////////////////////////  ///Function:    ~COptExcel  ///Description: 析构函数,释放对象,非常重要,不全部释放,占用内存,下  ///             一次使用此类时会中断  ///Call:        ReleaseDispatch()  ////////////////////////////////////////////////////////////////////////  COptExcel::~COptExcel(void)  {      books.ReleaseDispatch();      book.ReleaseDispatch();      sheets.ReleaseDispatch();      sheet.ReleaseDispatch();      range.ReleaseDispatch();      font.ReleaseDispatch();      cell.ReleaseDispatch();      app.Quit();      app.ReleaseDispatch();      ::CoUninitialize();  }  ////////////////////////////////////////////////////////////////////////  ///Function:    OpenExcelBook  ///Description: 打开表名为filename的文件,注意,文件路径非自动生成,以后  ///             考虑从下处理方法  ///Call:        GetAppPath()  ///Input:       CString filename 文件名  ////////////////////////////////////////////////////////////////////////  bool COptExcel::OpenExcelBook(CString filename)  {      CFileFind filefind;       if( !filefind.FindFile(filename) )       {           AfxMessageBox(_T("文件不存在"));          return false;      }      LPDISPATCH lpDisp; //接口指针      books=app.GetWorkbooks();      lpDisp = books.Open(filename,          covOptional, covOptional, covOptional, covOptional,          covOptional, covOptional, covOptional, covOptional,          covOptional, covOptional, covOptional, covOptional,          covOptional, covOptional          );                                      //与office 2000的不同,是个参数的,直接在后面加了两个covOptional成功了      book.AttachDispatch(lpDisp);      sheets=book.GetSheets();      sheet=sheets.GetItem(COleVariant((short)1));        //与的不同,是个参数的,直接在后面加了两个covOptional成功了      return true;  }  void COptExcel::NewExcelBook()  {      books=app.GetWorkbooks();      book=books.Add(covOptional);      sheets=book.GetSheets();      sheet=sheets.GetItem(COleVariant((short)1));        //与的不同,是个参数的,直接在后面加了两个covOptional成功了  }  ////////////////////////////////////////////////////////////////////////  ///Function:    OpenExcelApp  ///Description: 打开应用程序(要注意以后如何识别用户要打开的是哪个文件)  ////////////////////////////////////////////////////////////////////////  void COptExcel::OpenExcelApp(void)  {      app.SetVisible(TRUE);      app.SetUserControl(TRUE);  }  ////////////////////////////////////////////////////////////////////////  ///Function:    SaveExcel  ///Description: 用于打开数据文件,续存数据后直接保存  ////////////////////////////////////////////////////////////////////////  void COptExcel::SaveExcel(void)  {      book.SetSaved(TRUE);  }  ////////////////////////////////////////////////////////////////////////  ///Function:    SaveAsExcel  ///Description: 保存excel文件  ////////////////////////////////////////////////////////////////////////  void COptExcel::SaveAsExcel(CString filename)  {      book.SaveAs(COleVariant(filename),covOptional,      covOptional,covOptional,      covOptional,covOptional,(long)0,covOptional,covOptional,covOptional,      covOptional,covOptional);                     }  ////////////////////////////////////////////////////////////////////////  ///Function:    SetCellValue  ///Description: 修改单元格内的值  ///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  ///Input:       int row 单元格所在行  ///             int col 单元格所在列  ///             int Align       对齐方式默认为居中  ////////////////////////////////////////////////////////////////////////  void COptExcel::SetCellValue(int row, int col,int Align)  {      range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));      range.SetValue2(COleVariant(value));      cell.AttachDispatch((range.GetItem (COleVariant(long(1)), COleVariant(long(1)))).pdispVal);      cell.SetHorizontalAlignment(COleVariant((short)Align));  }  ////////////////////////////////////////////////////////////////////////  ///Function:    GetCellValue  ///Description: 得到的单元格中的值  ///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  ///Input:       int row 单元格所在行  ///             int col 单元格所在列  ///Return:      CString 单元格中的值  ////////////////////////////////////////////////////////////////////////  CString COptExcel::GetCellValue(int row, int col)  {      range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));      COleVariant rValue;      rValue=COleVariant(range.GetValue2());      rValue.ChangeType(VT_BSTR);      return CString(rValue.bstrVal);  }  ////////////////////////////////////////////////////////////////////////  ///Function:    SetRowHeight  ///Description: 设置行高  ///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  ///Input:       int row 单元格所在行  ////////////////////////////////////////////////////////////////////////  void COptExcel::SetRowHeight(int row, CString height)  {      int col = 1;      range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));      range.SetRowHeight(COleVariant(height));  }  ////////////////////////////////////////////////////////////////////////  ///Function:    SetColumnWidth  ///Description: 设置列宽  ///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  ///Input:       int col 要设置列宽的列  ///             CString 宽值  ////////////////////////////////////////////////////////////////////////  void COptExcel::SetColumnWidth(int col,CString width)  {      int row = 1;      range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));      range.SetColumnWidth(COleVariant(width));  }  ////////////////////////////////////////////////////////////////////////  ///Function:    SetRowHeight  ///Description: 设置行高  ///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  ///Input:       int row 单元格所在行  ////////////////////////////////////////////////////////////////////////  CString COptExcel::GetColumnWidth(int col)  {      int row = 1;      range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));      VARIANT width = range.GetColumnWidth();      CString strwidth;      strwidth.Format(CString((LPCSTR)(_bstr_t)(_variant_t)width));      return strwidth;  }  ////////////////////////////////////////////////////////////////////////  ///Function:    GetRowHeight  ///Description: 设置行高  ///Call:        IndexToString() 从(x,y)坐标形式转化为“A1”格式字符串  ///Input:       int row 要设置行高的行  ///             CString 宽值  ////////////////////////////////////////////////////////////////////////  CString COptExcel::GetRowHeight(int row)  {      int col = 1;      range=sheet.GetRange(COleVariant(IndexToString(row,col)),COleVariant(IndexToString(row,col)));      VARIANT height = range.GetRowHeight();      CString strheight;      strheight.Format(CString((LPCSTR)(_bstr_t)(_variant_t)height));      return strheight;  }  ////////////////////////////////////////////////////////////////////////  ///Function:    IndexToString  ///Description: 得到的单元格在EXCEL中的定位名称字符串  ///Input:       int row 单元格所在行  ///             int col 单元格所在列  ///Return:      CString 单元格在EXCEL中的定位名称字符串  ////////////////////////////////////////////////////////////////////////  CString COptExcel::IndexToString( int row, int col )   {       CString strResult;      if( col > 26 )       {           strResult.Format(_T("%c%c%d"),'A' + (col-1)/26-1,'A' + (col-1)%26,row);      }       else       {           strResult.Format(_T("%c%d"), 'A' + (col-1)%26,row);      }       return strResult;  }   ////////////////////////////////////////////////////////////////////////  ///Function:    LastLineIndex  ///Description: 得到表格总第一个空行的索引  ///Return:      int 空行的索引号  ////////////////////////////////////////////////////////////////////////  int COptExcel::LastLineIndex()   {       int i,j,flag=0;      CString str;      for(i=1;;i++)      {          flag = 0;          //粗略统计,认为前列都没有数据即为空行          for(j=1;j<=5;j++)          {              str.Format(_T("%s"),this->GetCellValue(i,j).Trim());              if(str.Compare(_T(""))!=0)              {                  flag = 1;                  break;              }          }          if(flag==0)              return i;      }  }  
0 0
原创粉丝点击