vs2008下用MFC读写excel文件

来源:互联网 发布:网络投诉电话 编辑:程序博客网 时间:2024/05/17 01:25

我的介绍主要分为下面3大步:

1、导入excel相关的类

2、从excel表格中读取数据

3、向excel表格中写入数据

4、部分代码解释

然后下面分别介绍:

一、导入excel相关的类:

1、建立MFC工程,基于对话框的,其他的都默认。

2、对excel表格进行操作的初始化

a、project->add class->MFC class from typelib(项目->添加类->Typelib中的MFC类) ,注册表不用管(默认的就行),选择文件,导入EXCEL.EXE(我的是excel 2007,这个文件在你excel 安装目录的 Office12下面)

b、选中以下几项_Application,_WorkSheet,_WorkBook,WorkSheets,WorkBooks,Range,然后导入,导入后会自动在工程中加入CApplication,CWorkSheet,CWorkBook,CWorkSheets,CWorkBooks,CRange这些类;然后需要把这些类的头文件中的第一句话#"......EXCEL.EXE" nonamespace删除,然后将CRange类中的

VARIANT DialogBox()
{
VARIANT result;
InvokeHelper(0xf5, DISPATCH_METHOD, VT_VARIANT, (void*)&result, NULL);
return result;
}

DialogBox前面加“_“变为_DialogBox

c、打开COM口:在MFC的应用程序类的InitInstance()函数中添加AfxOleInit();

二、从excel表格中读取数据

当然刚开始自己要添加一个按钮,将下面的代码写到按钮的消息响应函数中

a:读取excel的一个单元格,代码如下:

CApplication app1;
CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CRange range;
CRange iCell;
LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
if(!app1.CreateDispatch(_T("Excel.Application"),NULL))
  {   
  AfxMessageBox(_T("无法启动Excel服务器!"));  
  return;   
  }    
  books.AttachDispatch(app1.get_Workbooks());   
  lpDisp = books.Open("D:\\test.xlsx",covOptional, covOptional, covOptional , covOptional, covOptional,covOptional, covOptional, covOptional, covOptional, covOptional,covOptional, covOptional, covOptional,covOptional);  


  //得到Workbook    
  book.AttachDispatch(lpDisp); 
  //得到Worksheets   
  sheets.AttachDispatch(book.get_Worksheets());  


  //得到当前活跃sheet   
  //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待   
  lpDisp=book.get_ActiveSheet();  
  sheet.AttachDispatch(lpDisp);   
  //读取第一个单元格的值   
  range.AttachDispatch(sheet.get_Cells());   
  range.AttachDispatch(range.get_Item (COleVariant((long)2),COleVariant((long)1)).pdispVal );   
   vResult=range.get_Value2();  
  CString str;    
  if(vResult.vt==VT_BSTR) //字符串  
  {   
  str=vResult.bstrVal;  
  }    
  else if (vResult.vt==VT_R8) //8字节的数字  
  {    
  str.Format("%f",vResult.dblVal);   
  }  


                                     // app1.put_Visible(TRUE);
//app1.put_UserControl(TRUE);
  books.Close();    
  app1.Quit();             // 退出  
  //释放对象      
  range.ReleaseDispatch();   
  sheet.ReleaseDispatch();  
  sheets.ReleaseDispatch();  
  book.ReleaseDispatch();   
  books.ReleaseDispatch();  
  app1.ReleaseDispatch();  
  //OnOK();  
  MessageBox(str);

//读取D:\\test.xlsx的单元格(2,1)里面的数据,有MessageBox显示出来

b:读取excel表格中一片区域的数据,例子中的区域是A1到M46的这个区域,并用AfxMessageBox显示出来,代码如下:

CApplication oExcel;

CWorkbook oBook;

CWorksheets oSheets;

CWorksheet oSheet;
CRange oRange;
LPDISPATCH lpDisp;
CWorkbooks books;
   COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
   if(!oExcel.CreateDispatch(_T("Excel.Application"),NULL))
   {   
  AfxMessageBox(_T("无法启动Excel服务器!"));  
  return;   
   } 
   books= oExcel.get_Workbooks(); 
   lpDisp = books.Open("D:\\test.xlsx",covOptional, covOptional, covOptional , covOptional, covOptional,covOptional, covOptional, covOptional, covOptional, covOptional,covOptional, covOptional, covOptional,covOptional);  
   oBook.AttachDispatch(lpDisp); 
   oSheets = oBook.get_Worksheets();
   oSheet = oSheets.get_Item(COleVariant((short)1));
   // Set the range of data to retrieve
   oRange = oSheet.get_Range(COleVariant("A1"),COleVariant("M46"));
   // Get the data.
   COleSafeArray saRet(oRange.get_Value(covOptional));




   long iRows;
   long iCols;
   saRet.GetUBound(1, &iRows);
   saRet.GetUBound(2, &iCols);


   CString valueString = "Array Data:\r\n";
   long index[2];
   for (int rowCounter = 1; rowCounter <= iRows; rowCounter++) {
  for (int colCounter = 1; colCounter <= iCols; colCounter++) {
  index[0]=rowCounter;
  index[1]=colCounter;  
  COleVariant vData;
  saRet.GetElement(index,vData);
  CString szdata(vData);
  valueString += szdata;
  valueString += "\t";
  }
  valueString += "\r\n";
   }
   
   AfxMessageBox(valueString,MB_SETFOREGROUND,NULL);

//读取的也是D:\\test.xlsx,读取的内容相当于是放在一个46行,13列的矩阵,要注意,index的值就是单元格所在的行和列

三、向excel表格中写入数据

a:向excel的一个表格中写入数据,代码如下:

CApplication app1;
CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CRange range;
CRange iCell;
LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
if(!app1.CreateDispatch(_T("Excel.Application"),NULL))
{   
AfxMessageBox(_T("无法启动Excel服务器!"));  
return;   
}    
books.AttachDispatch(app1.get_Workbooks());  
 lpDisp = books.Open("E:\\test.xlsx",covOptional, covOptional, covOptional , covOptional, covOptional,covOptional, covOptional, covOptional, covOptional, covOptional,covOptional, covOptional, covOptional,covOptional);  
 book.AttachDispatch(lpDisp); 
 //得到Worksheets   
 sheets.AttachDispatch(book.get_Worksheets());  


 //得到当前活跃sheet   
 //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待   
 lpDisp=book.get_ActiveSheet();  
 sheet.AttachDispatch(lpDisp);   
 //读取第一个单元格的值   
 range.AttachDispatch(sheet.get_Cells());   
 range.put_Item(COleVariant(long(1)),COleVariant(long(1)),COleVariant("so"));
     app1.put_Visible(TRUE);
 app1.put_UserControl(TRUE);

//向单元格(1,1)写入"so",这个是在已知的E:\\test.xlsx中写入

b:向excel表格的一个区域中写入数据,代码如下:

CApplication oExcel;
CWorkbook oBook;
CWorkbooks oBooks;
CWorksheets oSheets;
CWorksheet oSheet;
CRange oRange;
COleVariant covOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);


// If you have not created Excel, create a new instance.
if (oExcel.m_lpDispatch == NULL) {
oExcel.CreateDispatch("Excel.Application");
}
// Show Excel to the user.
oExcel.put_Visible(TRUE);
oExcel.put_UserControl(TRUE);


// Add a new workbook and get the first worksheet in that book.
oBooks = oExcel.get_Workbooks();
oBook = oBooks.Add(covOptional);
oSheets = oBook.get_Worksheets();
oSheet = oSheets.get_Item(COleVariant((short)1));


// Get a range of data.
oRange = oSheet.get_Range(COleVariant("A1"),covOptional);
oRange = oRange.get_Resize(COleVariant((short)5),COleVariant((short)5));


COleSafeArray saRet;
DWORD numElements[2];
numElements[0] = 5;
numElements[1] = 5;


long index[2];
// Create a BSTR or double safe array.
saRet.Create(VT_BSTR,2,numElements);


// Fill the array with data.
for (int iRow = 1; iRow <= 5; iRow++) {
for (int iCol = 1; iCol <= 5; iCol++) {
index[0]=iRow-1;
index[1]=iCol-1;
CString szTemp;
szTemp.Format("%d|%d",iRow,iCol);
BSTR bstr = szTemp.AllocSysString();
saRet.PutElement(index,bstr);
SysFreeString(bstr);

}
}
}
// Send the array to Excel.
oRange.put_Value(covOptional,COleVariant(saRet));

//这是新建一个表,并且在这个表的矩阵5*5的区域写入数据,要注意索引的值,也就是一个是iRow-1,一个是iCol-1,和读取的时候是不一样的

四、部分代码解释:

CApplication oExcel;  //CApplication代表了EXCEL服务器   
    CWorkbooks oBooks;//CWorkbooks表示整个Excel服务器(表现为一个.xls文件)里所有的表,(可以通过"新建"得到多个表,即MDI程序里的一个视窗一样,所有的视窗就是workbooks),  
    CWorkbook oBook;//CWorkbook就是一个表,相当于MDI中的一个视窗,  
    CWorksheets oSheets; // CWorksheets表示所有的表单,每个表都可能有很多表单(建立一个Excel文件之后,打开,可以看到有sheet1,sheet2等,所有这些sheetn就组成了worksheets)   
    CWorksheet oSheet;//CWorksheet就表示一个表单, 
    CRange objRange,usedRange;//CRange 表示元素的集合  

oExcel.put_Visible(TRUE);//打开Excel程序,没有显示任何数据
oExcel.put_UserControl(TRUE);//允许其他用户控制Excel,否则Excel将一闪而逝

LPDISPATCH lpDisp//一个指向excel对象的指针

























0 0
原创粉丝点击