我想用ATL开发一个读取EXCEL文件的控件,请问如何实现?因为EXCEL有不同的版本,包含的头文件也有区别,函数也有不同,应该如何统一?希望高手能给个例子!

解决方案 »

  1.   

    我用ATL编写了一个Excel文件的访问器,对我自己的Excel文件访问不会有任何问题,但访问客户的Excel文件就有问题,得不到任何数据,不知道是什么回事,代码如下:#ifndef __EXCEL_OBJECT_H__
    #define __EXCEL_OBJECT_H__namespace Excel
    {
    class ExcelApplication;
    class ExcelWorkbooks;
    class ExcelWorkbook;
    class ExcelWorksheets;
    class ExcelWorksheet;
    class ExcelRange; class ExcelApplication : public CComQIPtr<IDispatch, &__uuidof(IDispatch)>
    {
    public:
    ExcelApplication();
    ~ExcelApplication();
    public:
    IDispatch* GetWorkbooks();
    void Quit();
    }; class ExcelWorkbooks : public CComQIPtr<IDispatch, &__uuidof(IDispatch)>
    {
    public:
    IDispatch* Open(const wchar_t* filename);
    void Close();
    }; class ExcelWorkbook : public CComQIPtr<IDispatch, &__uuidof(IDispatch)>
    {
    public:
    IDispatch* GetWorksheets();
    void Close();
    }; class ExcelWorksheets : public CComQIPtr<IDispatch, &__uuidof(IDispatch)>
    {
    public:
    IDispatch* GetWorksheet(long index);
    }; class ExcelWorksheet : public CComQIPtr<IDispatch, &__uuidof(IDispatch)>
    {
    public:
    IDispatch* GetCells();
    }; class ExcelRange : public CComQIPtr<IDispatch, &__uuidof(IDispatch)>
    {
    public:
    CComVariant GetItem(long iRow, long iCol);
    void SetItem(long iRow, long iCol, const wchar_t* val);
    CComVariant GetValue();
    void SetValue(CComVariant val);
    DWORD GetDataType(long iRow, long iCol);
    };}#endif
    //--------------------------------------------------------------------------------------------------------#include "stdafx.h"
    #include "ExcelObject.h"namespace Excel
    {
    ExcelApplication::ExcelApplication()
    {
    CLSID clsid;
    HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid); ATLASSERT(p == NULL); if(SUCCEEDED(hr))
    {
    IUnknown* iUnknown = 0;
    hr = ::CoCreateInstance(clsid, 0, CLSCTX_ALL, __uuidof(iUnknown), (void**)&iUnknown);
    if(SUCCEEDED(hr))
    {
    hr = ::OleRun(iUnknown);
    if(SUCCEEDED(hr))
    {
    hr = iUnknown->QueryInterface(IID_IDispatch, (void**)&p);
    }
    }
    }
    } ExcelApplication::~ExcelApplication()
    {
    this->Quit();
    } IDispatch* ExcelApplication::GetWorkbooks()
    {
    if(this->p == 0)
    return 0; CComVariant result;
    if(this->GetProperty(0x023c, &result) != S_OK)
    {
    return 0;
    }
    if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp);
    return temp.pdispVal;
    }
    else
    {
    return 0;
    }
    } void ExcelApplication::Quit()
    {
    if(this->p != 0)
    this->Invoke0(0x012e, 0);
    } //---- IDispatch* ExcelWorkbooks::Open(const wchar_t* filename)
    {
    if(this->p == 0)
    return 0; CComVariant param = filename;
    CComVariant result;
    if(this->Invoke1(0x0783, &param, &result) != S_OK)
    {
    return 0;
    }
    else if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp);
    return temp.pdispVal;
    }
    else
    {
    return 0;
    }
    } void ExcelWorkbooks::Close()
    {
    if(this->p != 0)
    this->Invoke0(0x0115, 0);
    } //---- IDispatch* ExcelWorkbook::GetWorksheets()
    {
    if(this->p == 0)
    return 0; CComVariant result;
    if(this->GetProperty(0x01ee, &result) != S_OK)
    {
    return 0;
    }
    else if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp);
    return temp.pdispVal;
    }
    else
    {
    return 0;
    }
    } void ExcelWorkbook::Close()
    {
    if(this->p == 0)
    return; CComVariant params[3];
    params[0] = TRUE;
    this->InvokeN(0x0115, params, 1, 0);
    } //---- IDispatch* ExcelWorksheets::GetWorksheet(long index)
    {
    if(this->p == 0)
    return 0; DISPPARAMS dispparams;
    memset(&dispparams, 0, sizeof dispparams); DISPID dispidNamed = DISPID_PROPERTYPUT;
    CComVariant param = index; dispparams.cArgs = 1;
    dispparams.rgdispidNamedArgs = &dispidNamed;
    dispparams.rgvarg = &param; CComVariant result;
    if(this->p->Invoke(0x00aa, IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &result, 0, 0) != S_OK)
    {
    return 0;
    }
    else if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp);
    return temp.pdispVal;
    }
    else
    {
    return 0;
    }
    } //---- IDispatch* ExcelWorksheet::GetCells()
    {
    if(this->p == 0)
    return 0; CComVariant result;
    if(this->GetProperty(0x00ee, &result) != S_OK)
    {
    return 0;
    }
    else if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp);
    return temp.pdispVal;
    }
    else
    {
    return 0;
    }
    } //---- CComVariant ExcelRange::GetItem(long iRow, long iCol)
    {
    CComVariant result; if(this->p == 0)
    return result; DISPPARAMS dispparams;
    memset(&dispparams, 0, sizeof dispparams); DISPID dispidNamed = DISPID_PROPERTYPUT;
    CComVariant param[2] = { iRow, iCol }; dispparams.cArgs = 2;
    dispparams.rgdispidNamedArgs = &dispidNamed;
    dispparams.rgvarg = param; if(this->p->Invoke(0x00aa, IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &result, 0, 0) != S_OK)
    {
    return 0;
    }
    else if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp);
    return temp.pdispVal;
    }
    else
    {
    return 0;
    }
    } void ExcelRange::SetItem(long iRow, long iCol, const wchar_t* val)
    {
    if(this->p == 0)
    return; DISPPARAMS dispparams;
    memset(&dispparams, 0, sizeof dispparams); DISPID dispidNamed = DISPID_PROPERTYPUT;
    CComVariant param[3] = { iRow, iCol, val }; dispparams.cArgs = 3;
    dispparams.rgdispidNamedArgs = &dispidNamed;
    dispparams.rgvarg = param; this->p->Invoke(0x00aa, IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, 0, 0, 0);
    } CComVariant ExcelRange::GetValue()
    {
    CComVariant result;
    if(this->p != 0)
    this->GetProperty(0x056c, &result);
    return result;
    } void ExcelRange::SetValue(CComVariant val)
    {
    if(this->p != 0)
    this->PutProperty(0x056c, &val);
    } DWORD ExcelRange::GetDataType(long iRow, long iCol)
    {
    if(this->p == 0)
    return VT_EMPTY; DISPPARAMS dispparams;
    memset(&dispparams, 0, sizeof dispparams); DISPID dispidNamed = DISPID_PROPERTYPUT;
    CComVariant param[2] = { iRow, iCol }; dispparams.cArgs = 2;
    dispparams.rgdispidNamedArgs = &dispidNamed;
    dispparams.rgvarg = param; CComVariant result; if(this->p->Invoke(0x00aa, IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &result, 0, 0) != S_OK)
    {
    return VT_EMPTY;
    }
    else if(result.vt == VT_DISPATCH)
    {
    VARIANT temp;
    temp.vt = VT_EMPTY;
    result.Detach(&temp); ExcelRange item;
    item.Attach(temp.pdispVal); if(item.GetProperty(0x056c, &result) == S_OK)
    return result.vt;
    else
    return VT_EMPTY;
    }
    else
    {
    return VT_EMPTY;
    }
    }}哪位高手抽空看看是什么回事啊?