Excel和vs2010 的连接(续)

通过VS实现对Excel表格的操作的方法有多种,如:通过ODBC数据库实现,通过解析Excel表格文件,通过OLE/COM的实现。本文通过OLE/COM实现对Excel表格的操作
1. 建立MFC工程,MDI(基于对话框),其他默认即可。
2. 操作Excel文件的配置:
a.项目->添加类->TypeLib中的MFC类,导入Excel.exe,一般都在C:\Program Files\Microsoft Office\Office14\EXCEL.EXE路径下(即选择你的office安装路径下的excel.exe加入)。
b.选中以下几项_Application,_WorkSheet,_WorkBook,WorkSheets,WorkBooks,Range导入,导入后自动在工程中添加CApplication, CWorkSheet, CWorkBook, CWorkSheets, CWorkBooks, CRange这些类。
c.把这些类的头文件中的第一句话 #import ".......EXCEL.EXE" nonamespace 删除;这行代码的作用是导入Excel整个类型库到工程中。
d.引入之后如果编译遇到错误,Not enough actual parameters for macro 'DialogBoxW'。解决方法是在CRange类中,DialogBox()前面添加下划线变成_DialogBox()。

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

3.操作excel文件
在XXX.cpp头文件下添加:

#include "CApplication.h"  
#include "CRange.h"  
#include "CWorkbook.h"  
#include "CWorkbooks.h"  
#include "CWorksheet.h"  
#include "CWorksheets.h"

在对话框中添加“新建”按钮,编写事件响应函数如下:

void Cvs_excelDlg::OnBnClickedNew()
{
    // TODO: 在此添加控件通知处理程序代码
    //Excel初始化
    CApplication app;  
    CWorkbooks books;  
    CWorkbook book;  
    CWorksheets sheets;  
    CWorksheet sheet;  
    CRange range;   
    LPDISPATCH lpDisp;  
    //COleVariant vResult;  
    COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
    if(!app.CreateDispatch("Excel.Application"))  
    {  
        AfxMessageBox("无法启动Excel服务器!");  
        return;  
    }  
    books.AttachDispatch(app.get_Workbooks(),TRUE);
    book=books.Add(covOptional);
    sheets.AttachDispatch(book.get_Worksheets(),TRUE);  
    sheet=sheets.get_Item(COleVariant((short)1));
    range.AttachDispatch(sheet.get_Cells()); 

    //Excel文件头
    range.put_Item(_variant_t(1),_variant_t(1), _variant_t("序号"));
    range.put_Item(_variant_t(1),_variant_t(2), _variant_t("识别时间"));
    range.put_Item(_variant_t(1),_variant_t(3), _variant_t("原始图片文件名称"));
    range.put_Item(_variant_t(1),_variant_t(4), _variant_t("识别后电话号码"));
    //Excel宽度
    range = sheet.get_Range(COleVariant(_T("A1")),COleVariant(_T("A1")));
    range.put_ColumnWidth(_variant_t((long)8));
    range = sheet.get_Range(COleVariant(_T("B1")),COleVariant(_T("B1")));
    range.put_ColumnWidth(_variant_t((long)19));
    range = sheet.get_Range(COleVariant(_T("C1")),COleVariant(_T("C1")));
    range.put_ColumnWidth(_variant_t((long)25));
    range = sheet.get_Range(COleVariant(_T("D1")),COleVariant(_T("D1")));
    range.put_ColumnWidth(_variant_t((long)17));
    //时间
     CTime tm=CTime::GetCurrentTime(); 
    CString sttime=tm.Format("%Y/%m/%d");
    //保存结果至EXCEL
    range.AttachDispatch(sheet.get_Cells());  
    range.put_NumberFormat(COleVariant("@")); 
    range.put_Item(_variant_t(2),_variant_t(1), _variant_t("1"));
    range.put_Item(_variant_t(2),_variant_t(2), _variant_t(sttime));
    range.put_Item(_variant_t(2),_variant_t(3), _variant_t("C:\\test"));
    range.put_Item(_variant_t(2),_variant_t(4), _variant_t("8810769206"));

    //保存Excel文件
    book.SaveCopyAs(COleVariant("C:\\test.xlsx"));
    book.put_Saved(true);
    books.Close();
    //释放对象    
    range.ReleaseDispatch();  
    sheet.ReleaseDispatch();  
    sheets.ReleaseDispatch();  
    book.ReleaseDispatch();  
    books.ReleaseDispatch();  
    app.Quit();             // 退出  
    app.ReleaseDispatch(); 
}

在对话框中添加“打开”按钮,编写事件响应函数如下:

void Cvs_excelDlg::OnBnClickedOpen()
{
    // TODO: 在此添加控件通知处理程序代码
     CApplication app;  
    CWorkbooks books;  
    CWorkbook book;  
    CWorksheets sheets;  
    CWorksheet sheet;  
    CRange range; 
    LPDISPATCH lpDisp;  
    COleVariant vResult;  
    COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  
    if(!app.CreateDispatch("Excel.Application"))  
    {  
        AfxMessageBox("无法启动Excel服务器!");  
        return;  
    }
    books.AttachDispatch(app.get_Workbooks());  
    
lpDisp = books.Open("C:\\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); sheet=sheets.get_Item(COleVariant((short)1)); //读取第一个单元格的值 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); } /*else if(vResult.vt==VT_DATE) //时间格式 { SYSTEMTIME st; VariantTimeToSystemTime(&vResult.date, &st); } else if(vResult.vt==VT_EMPTY) //单元格空的 { str=""; }*/ books.Close(); //释放对象 range.ReleaseDispatch(); sheet.ReleaseDispatch(); sheets.ReleaseDispatch(); book.ReleaseDispatch(); books.ReleaseDispatch(); app.Quit(); // 退出
app.ReleaseDispatch();
    MessageBox(str);  
}

这样便实现了Excel的读写操作,具体功能比较简单,详见代码吧。
4.
如果你想要的到更多的功能实现可以参考:http://blog.csdn.net/fullsail/article/details/8449448。它对Excel的操作做了进一步的类封装,比较完善。

posted @ 2013-06-02 20:21  侯凯  阅读(1904)  评论(0编辑  收藏  举报