用vc++操作微软Excel的实例,愿愿原创。

以下是aboExcel.h文件内容,应原创作者要求,保留了他的说明,本人在此只是加以完善,当然改动的地方很多,尤其是用了智能指针的自动释放功能。本文没有说明如何在vc开发环境导入Excel库,因为网上该经验很多。

#ifndef _abaoExcel_h_

/************************************
REVISION LOG ENTRY
Revision By: abao++
Revised on 2006-8-11 8:13:07
Comments: ...
看了无数关于vc调用excel的贴,可是都是原始的方法,用起来一个字,不方便
为了做一个项目,特封装了一个类,功能那是非常之。。。。。。。。。。弱弱的。
不过一般简单的excel文档可以搞定了。而且,这个是可以扩展,可以继承的,,继承就免了吧,
改一下俺不会告你侵权的,不过最好不要擦除俺的功劳,虽然俺只写了几个简单函数

愿愿进一步完善。

调用前请确保已经调用了如下函数初始化com库,

if (CoInitialize(NULL)!=0)
{
AfxMessageBox("初始化COM支持库失败!");
exit(1);
}
************************************/

#define _abaoExcel_h_

#include <comdef.h>
#include "capplication.h"
#include "CBorder.h"
#include "CBorders.h"
#include "CRange.h"
#include "CRanges.h"
#include "cworkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "CComment.h"
#include "CComments.h"
#include "CShape.h"
#include "CTextFrame.h"
#include "CFont0.h"
#include <memory>
#include <functional>
enum RangeHAlignment{HAlignDefault=1,HAlignCenter=-4108,HAlignLeft=-4131,HAlignRight=-4152};
enum RangeVAlignment{VAlignDefault=2,VAlignCenter=-4108,VAlignTop=-4160,VAlignBottom=-4107};
class _cEXCELMemberDeleter{
    // What should be the default?? No deleter? delete? I choose to
    // mimic the default of unique_ptr.
public:
    _cEXCELMemberDeleter(): f([](COleDispatchDriver *p){
        if(NULL!=p){
            if(NULL!=p->m_lpDispatch)
            p->ReleaseDispatch();
            delete p;
        }
    })
        {};
        // allow the user to specify what type of deleter to use
        explicit _cEXCELMemberDeleter(std::tr1::function< void(COleDispatchDriver *)> const &f_ )
            : f(f_)
        {};

        void operator()(COleDispatchDriver *p) const
        {
            f(p);
        };

private:
    std::tr1::function< void(COleDispatchDriver *)> f;
};

typedef std::unique_ptr<CRange,_cEXCELMemberDeleter> _cUnpEXCELRg;
typedef std::unique_ptr<CBorders,_cEXCELMemberDeleter> _cUnpEXCELBds;
typedef std::unique_ptr<CBorder,_cEXCELMemberDeleter> _cUnpEXCELBd;
typedef std::unique_ptr<CComments,_cEXCELMemberDeleter> _cUnpEXCELCms;
typedef std::unique_ptr<CComment,_cEXCELMemberDeleter> _cUnpEXCELCm;
typedef std::unique_ptr<CShape,_cEXCELMemberDeleter> _cUnpEXCELSp;
typedef std::unique_ptr<CTextFrame,_cEXCELMemberDeleter> _cUnpEXCELTF;
typedef std::unique_ptr<CFont0,_cEXCELMemberDeleter> _cUnpEXCELFt0;
class AbaoComments
{
private:
    //bool _isNull;
    const _cUnpEXCELCms cms;
    //const _cUnpEXCELRg funInit(const _cUnpEXCELRg& m_unpRange);
    //static const _cUnpEXCELRg& rgNULL;
    //static const _cUnpEXCELRg& rgNomal;
public:

    
    ~AbaoComments();
     //operator AbaoRange*() { return _isNull ? nullptr : this; }
    AbaoComments();
    AbaoComments& operator=(LPDISPATCH&& disComments);
    LPUNKNOWN get__NewEnum(void);
};
class AbaoComment
{
private:
    //bool _isNull;
    const _cUnpEXCELCm cm;
    //const _cUnpEXCELRg funInit(const _cUnpEXCELRg& m_unpRange);
    //static const _cUnpEXCELRg& rgNULL;
    //static const _cUnpEXCELRg& rgNomal;
public:

    
    ~AbaoComment();
     //operator AbaoRange*() { return _isNull ? nullptr : this; }
    AbaoComment();
    AbaoComment& operator=(LPDISPATCH&& unpComment);//赋值另一个unpComment
    CString Text(VARIANT& Text, VARIANT& Start, VARIANT& Overwrite);
};
class AbaoRange
{
private:

    const _cUnpEXCELRg rg;

public:

    
    ~AbaoRange();
     //operator AbaoRange*() { return _isNull ? nullptr : this; }
    AbaoRange();
    BOOL Merge();//合并
    const AbaoRange& operator=(const CString& s); //填入一个s,,
    const AbaoRange& operator=(const TCHAR* str);//填入char*
    AbaoRange& operator=(LPDISPATCH&& unpRange);//赋值另一个m_unpRange
    LPDISPATCH GetComment(void);
    BOOL Border(const short &mode=1,const long &BoderWidth=1,const long &ColorIndex=1, VARIANT &color=COleVariant((long)DISP_E_PARAMNOTFOUND,VT_ERROR));
    //设置边框,参数我还没有弄清楚
    BOOL BorderALL(const short &mode=1,const long &BoderWidth=1,const long &ColorIndex=1,VARIANT &color=COleVariant((long)DISP_E_PARAMNOTFOUND,VT_ERROR));
    ////BOOL SetHAlign(RangeHAlignment mode=HAlignDefault);
    //////设置对齐方式
    ////BOOL SetVAlign(RangeVAlignment mode=VAlignDefault);
    BOOL SetNumberFormat(const CString& s);
    LPDISPATCH get_Rows(void);
    LPDISPATCH get_Columns(void);
    long get_Count(void);
long get_Column();
long get_Row();
BOOL put_RowHeight(VARIANT& newValue);
BOOL put_ColumnWidth(VARIANT& newValue);
    VARIANT TextToColumns(VARIANT& Destination, long DataType, long TextQualifier, VARIANT& ConsecutiveDelimiter, VARIANT& Tab, VARIANT& Semicolon, VARIANT& Comma, VARIANT& Space, VARIANT& Other, VARIANT& OtherChar, VARIANT& FieldInfo, VARIANT& DecimalSeparator, VARIANT& ThousandsSeparator, VARIANT& TrailingMinusNumbers);
    LPDISPATCH SpecialCells(long Type, VARIANT& Value);
    BOOL ClearComments();
    VARIANT get_Text(void);
    VARIANT get_Formula(void);
    BOOL put_Formula(VARIANT& newValue);
VARIANT get_Value2(void);
    LPDISPATCH Find(VARIANT& What, VARIANT& After, VARIANT& LookIn, VARIANT& LookAt, VARIANT& SearchOrder, long SearchDirection, VARIANT& MatchCase, VARIANT& MatchByte, VARIANT& SearchFormat);

};

typedef std::unique_ptr<CApplication,_cEXCELMemberDeleter> _cUnpEXCELApp;
typedef std::unique_ptr<CWorkbooks,_cEXCELMemberDeleter> _cUnpEXCELWkBs;
typedef std::unique_ptr<CWorkbook,_cEXCELMemberDeleter> _cUnpEXCELWkB;
typedef std::unique_ptr<CWorksheets,_cEXCELMemberDeleter> _cUnpEXCELWkSs;
typedef std::unique_ptr<CWorksheet,_cEXCELMemberDeleter> _cUnpEXCELWkS;
typedef std::unique_ptr<CComments,_cEXCELMemberDeleter> _cUnpEXCELCms;

class AbaoExcel
{

public:

    //不使用裸指针的原因是为了
    //可以使得指针析构时,所拥有的对象也跟着析构
    //减少了对成员对象析构和内存可能泄漏的关注。
    //如果用了裸指针,那么它所指向的对象有可能没有被析构,产生内存泄漏

    //那么为什么不直接定义Excel相关对象的成员呢,
    //因为如果定义了相关成员,那么在_cMyExcel对象存在的期间
    //成员都存在,有可能浪费内存资源。当然在这里不存在这个区别
    //,因为_cMyExcel对象在构造同时用new构造了相关Excel对象。

    //用const的原因是为了保证,指针成员只能在构造中被赋值,
    //减少了可能在编程过程中,错误的再一次给它赋值.
    //收紧了对该类的使用限制,避免不必要的意外错误的发生。
    //建议将对象限制为由一个所有者所有,因为多个所有权会使程序逻辑变得复杂。

    const _cUnpEXCELApp m_unpApp; //excep
    const _cUnpEXCELWkBs m_unpWorkbooks; //m_unpWorkbooks
    const _cUnpEXCELWkB m_unpworkbook; //m_unpworkbook
    const _cUnpEXCELWkSs m_unpSheets; //m_unpSheet
    const _cUnpEXCELWkS m_unpSheet; //当前的表 ,可以通过SelectSheet 来改变
    BOOL   m_bIsNewApp;
    long   m_preDocsCount;
    long   m_afterDocsCount;
    //LPDISPATCH lpDisp;    // Often reused variable.
    AbaoExcel():m_unpApp(new CApplication),m_unpWorkbooks(new CWorkbooks)
    ,m_unpworkbook(new CWorkbook),m_unpSheets(new CWorksheets)
    ,m_unpSheet(new CWorksheet){};
    ~AbaoExcel();
    BOOL CreateApp(void);
    BOOL CloseApp(void);
    BOOL put_DisplayAlerts(BOOL bFlag);
    BOOL put_ScreenUpdating(BOOL bFlag);
    BOOL put_EnableEvents(BOOL bFlag);
    BOOL CloseWorkBook(void);
    BOOL open(const CString &Filename);
    BOOL openAllowWrite(const CString &Filename);
    LPDISPATCH ActiveSheet();//当前活动的m_unpSheet,在SelectSheet 后改变

    BOOL Add(const CString& ExtPath=CString(""));//从一个模版构造
    const _cUnpEXCELWkS& SelectSheet(const CString& SheetName);//选择一个已知表名的表
    const _cUnpEXCELWkS& SelectSheet(const char* SheetName){return SelectSheet(CString(SheetName));};//选择一个已知表名的表
    const _cUnpEXCELWkS& SelectSheet(const int &index);//选择一个已知表名的表
    BOOL SetALLCommentFontSize(const short &sizeValue);

    LPDISPATCH GetRange(const CString &RangeStart,const CString &RangeEnd);//获取m_unpRange,
    LPDISPATCH GetRange2(const CString &RangeStart);//获取m_unpRange,
    LPDISPATCH GetRange(const CString &RangeStr);//获取m_unpRange A1:A2模式
    LPDISPATCH get_UsedRange(void);
    LPDISPATCH ActiveSheetRange(void);//当前的m_unpRange,在使用GetRange后改变
    LPDISPATCH get_Comments(void);
    //BOOL MergeRange(const CString& RangeStr);//合并Range
    BOOL put_Saved(BOOL bFlag);
    BOOL put_AutoFilterMode(BOOL bFlag);
    BOOL Protect(VARIANT& Password, VARIANT& DrawingObjects, VARIANT& Contents, VARIANT& Scenarios, VARIANT& UserInterfaceOnly, VARIANT& AllowFormattingCells, VARIANT& AllowFormattingColumns, VARIANT& AllowFormattingRows, VARIANT& AllowInsertingColumns, VARIANT& AllowInsertingRows, VARIANT& AllowInsertingHyperlinks, VARIANT& AllowDeletingColumns, VARIANT& AllowDeletingRows, VARIANT& AllowSorting, VARIANT& AllowFiltering, VARIANT& AllowUsingPivotTables);
    BOOL Unprotect(VARIANT& Password);
    int get_SheetCount(void);
    CString get_SheetName(void);
    BOOL put_SheetName(LPCTSTR newValue);
    //int SetVisible(bool visible) {m_unpApp->put_Visible(visible);return 1;}//设置为可见以及隐藏
    BOOL SaveAs(const CString &FileName);//保存到文件名
    BOOL SaveAs2(const CString &FileName);
    BOOL CopySheet(LPDISPATCH sht);//复制一个m_unpSheet
    
};
class _cEXCELWrapDeleter{
    // What should be the default?? No deleter? delete? I choose to
    // mimic the default of unique_ptr.
public:
    _cEXCELWrapDeleter(): f([](AbaoExcel *p){
        if(NULL!=p){
            if(NULL!=p->m_unpworkbook->m_lpDispatch)
                p->CloseWorkBook();
            if(NULL!=p->m_unpApp->m_lpDispatch)
                p->CloseApp();
            delete p;}})
        {};
        // allow the user to specify what type of deleter to use
        explicit _cEXCELWrapDeleter(std::tr1::function< void(AbaoExcel *)> const &f_ )
            : f(f_)
        {};

        void operator()(AbaoExcel *p) const
        {
            f(p);
        };

private:
    std::tr1::function< void(AbaoExcel *)> f;
};
typedef std::unique_ptr<AbaoExcel,_cEXCELWrapDeleter> _cUnpAbaoExcel;
#endif

aboExcel.h文件结束。


以下是aboExcel.cpp文件内容,文件很长,有好多注释,不删除的目的是让读者以及c+v人更全面的了解微软Excel函数的使用方法。

#include "stdafx.h"

#include "abaoexcel.h"
#include "CommonFunction.h"
using namespace CommonFunction;
/************************************
REVISION LOG ENTRY
Revision By: abao++
Revised on 2006-8-11 8:13:15
Comments: ...
************************************/


//extern double Round(double value,unsigned int num);
//_cUnpEXCELRg AbaoRange::funInit(const _cUnpEXCELRg& m_unpRange)
//{
//    _cUnpEXCELRg retUnp(new CRange);
//    retUnp->AttachDispatch(m_unpRange->m_lpDispatch);
//    return retUnp;
//}
AbaoComments::AbaoComments():cms(new CComments)//funInit(m_unpRange)
{
}
AbaoComments::~AbaoComments()
{
}
AbaoComments& AbaoComments::operator=(LPDISPATCH&& disComments)
{
    cms->AttachDispatch(disComments);
    disComments=nullptr;
    return *this;
}
LPUNKNOWN AbaoComments::get__NewEnum(void)
{
    LPUNKNOWN lpDisp=nullptr;
    try{
        if(nullptr!=cms->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=cms->get__NewEnum();    
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
AbaoComment::AbaoComment():cm(new CComment)//funInit(m_unpRange)
{

}
AbaoComment::~AbaoComment()
{
}
AbaoComment& AbaoComment::operator=(LPDISPATCH&& unpComment)
{
    cm->AttachDispatch(unpComment);
    unpComment=nullptr;
    return *this;
}
CString AbaoComment::Text(VARIANT& Text, VARIANT& Start, VARIANT& Overwrite)
{
    CString tmpStr;
    try{
        tmpStr=cm->Text(Text,Start,Overwrite);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return tmpStr;
    }
    catch(...)
    {
        return tmpStr;////nullptr,BSTR)
    }
    return tmpStr;
}
AbaoRange::AbaoRange():rg(new CRange)//funInit(m_unpRange)
{
}
AbaoRange::~AbaoRange()
{
}
BOOL AbaoRange::Merge()
{
    try{
        rg->Merge(COleVariant((short)1));
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
const AbaoRange& AbaoRange::operator=(const CString& s)
{
    try{
        rg->put_Value2(COleVariant(s,VT_BSTRT));
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        rg->AttachDispatch(nullptr);
    }
    catch(...)
    {
        rg->AttachDispatch(nullptr);
    }
    return *this;
}
const AbaoRange& AbaoRange::operator=(const TCHAR* str)
{
    try{
        CString tmp=str;
        //tmp.Format(_T("%s"),str);
        rg->put_Value2(COleVariant(tmp,VT_BSTRT));
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        rg->AttachDispatch(nullptr);
    }
    catch(...)
    {
        rg->AttachDispatch(nullptr);
    }
    return *this;
}
AbaoRange& AbaoRange::operator=(LPDISPATCH&& unpRange)
{
    rg->AttachDispatch(unpRange);
    unpRange=nullptr;
    return *this;
}
//AbaoRange& AbaoRange::operator=(CRange& Range)
//{
//    rg=Range;
//    return *this;
//}
BOOL AbaoRange::SetNumberFormat(const CString& s)
{
    try{
        rg->put_NumberFormat(_variant_t(s));
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}

BOOL AbaoRange::Border(const short& mode,const long &BoderWidth,const long &ColorIndex, VARIANT &color)
{
    try{
        rg->BorderAround(COleVariant((short)mode),(long)BoderWidth,(long)ColorIndex,color);    
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}

BOOL AbaoRange::BorderALL(const short &mode,const long &BoderWidth,const long &ColorIndex, VARIANT &color)
{
    try{
        rg->BorderAround(COleVariant((short)mode),(long)BoderWidth,(long)ColorIndex,color);    
        _cUnpEXCELBds bds(new CBorders);
        bds->AttachDispatch(rg->get_Borders());
        _cUnpEXCELBd bd(new CBorder);
        bd->AttachDispatch(bds->get_Item(12));
        bd->put_LineStyle(COleVariant((short)1));
        bd->AttachDispatch(bds->get_Item(11));
        bd->put_LineStyle(COleVariant((short)1));
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
LPDISPATCH AbaoRange::get_Rows(void)
{
    LPDISPATCH lpDisp=nullptr;
    try{
        if(nullptr!=rg->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=rg->get_Rows();
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
LPDISPATCH AbaoRange::get_Columns(void)
{
    LPDISPATCH lpDisp=nullptr;
    try{
        if(nullptr!=rg->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=rg->get_Columns();
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
BOOL AbaoRange::ClearComments()
{
    try{
        rg->ClearComments();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
long AbaoRange::get_Count(void)
{
    try{
        return rg->get_Count();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return -1;
    }
    catch(...)
    {
        return -1;
    }
}
VARIANT AbaoRange::get_Text(void)
{
    VARIANT tmpVar;
    try{
        tmpVar=rg->get_Text();

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return tmpVar;
    }
    catch(...)
    {
        return tmpVar;//nullptr,BSTR)
    }
    return tmpVar;
}
VARIANT AbaoRange::get_Formula(void)
{
    VARIANT tmpVar;
    try{
        tmpVar=rg->get_Formula();

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return tmpVar;
    }
    catch(...)
    {
        return tmpVar;//nullptr,BSTR)
    }
    return tmpVar;
}
VARIANT AbaoRange::get_Value2(void)
{
    VARIANT tmpVar;
    try{
        tmpVar=rg->get_Value2();

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return tmpVar;
    }
    catch(...)
    {
        return tmpVar;//nullptr,BSTR)
    }
    return tmpVar;
}

BOOL AbaoRange::put_Formula(VARIANT& newValue)
{
    try{
        rg->put_Formula(newValue);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoRange::put_RowHeight(VARIANT& newValue)
{
    try{
        rg->put_RowHeight(newValue);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoRange::put_ColumnWidth(VARIANT& newValue)
{
    try{
        rg->put_ColumnWidth(newValue);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
VARIANT AbaoRange::TextToColumns(VARIANT& Destination, long DataType, long TextQualifier, VARIANT& ConsecutiveDelimiter, VARIANT& Tab, VARIANT& Semicolon, VARIANT& Comma, VARIANT& Space, VARIANT& Other, VARIANT& OtherChar, VARIANT& FieldInfo, VARIANT& DecimalSeparator, VARIANT& ThousandsSeparator, VARIANT& TrailingMinusNumbers)
{
    VARIANT tmpVar;
    try{
        tmpVar=rg->TextToColumns(Destination, DataType,TextQualifier, ConsecutiveDelimiter, Tab, Semicolon, Comma, Space,Other,OtherChar, FieldInfo, DecimalSeparator, ThousandsSeparator, TrailingMinusNumbers);

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return tmpVar;
    }
    catch(...)
    {
        return tmpVar;//nullptr,BSTR)
    }
    return tmpVar;
}

long AbaoRange::get_Column()
{
    try{
        return rg->get_Column();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return -1;
    }
    catch(...)
    {
        return -1;
    }
}
long AbaoRange::get_Row()
{
    try{
        return rg->get_Row();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return -1;
    }
    catch(...)
    {
        return -1;
    }
}
//int AbaoRange::SetHAlign(RangeHAlignment mode)
//{
//    rg.put_HorizontalAlignment(COleVariant((short)mode));
//    return 1;
//}
//int AbaoRange::SetVAlign(RangeVAlignment mode)
//{
//    rg.put_VerticalAlignment(COleVariant((short)mode));
//    return 1;
//}
//BOOL AbaoRange::autosize(void)
//{
//    try{
//    LPDISPATCH   lpDisp;//   Often   reused   variable.  
//    lpDisp   =   rg.get_Comment();
//    //CComment cm;
//    cm.AttachDispatch(lpDisp);
//    //cm.get_Parent()
//    lpDisp   =  cm.get_Shape();
//    //CShape sp;
//    sp.AttachDispatch(lpDisp);
//
//    //sp.put_Height(250);
//    //sp.put_Width(250);
//    //sp.pu
//    lpDisp   =  sp.get_TextFrame();
//    //CTextFrame tf;
//    tf.AttachDispatch(lpDisp);
//    //tf.g
//    tf.put_AutoSize(true);
//    }catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//}
//LPDISPATCH AbaoRange::SetComment2(void)
//{  
//    try{
//    return   rg->get_Comment();
//    }catch(...)
//    {
//        return nullptr;
//    }
//}
LPDISPATCH AbaoRange::GetComment(void)
{
    LPDISPATCH lpDisp=nullptr;
    try{
        if(nullptr!=rg->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=rg->get_Comment();    
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;

}
LPDISPATCH AbaoRange::Find(VARIANT& What, VARIANT& After, VARIANT& LookIn, VARIANT& LookAt, VARIANT& SearchOrder, long SearchDirection, VARIANT& MatchCase, VARIANT& MatchByte, VARIANT& SearchFormat)
{
    LPDISPATCH lpDisp=nullptr;
    try{
        if(nullptr!=rg->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=rg->Find(What, After, LookIn, LookAt, SearchOrder,SearchDirection, MatchCase, MatchByte, SearchFormat);    
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
LPDISPATCH AbaoRange::SpecialCells(long Type, VARIANT& Value)
{
    LPDISPATCH lpDisp=nullptr;
    try{
        if(nullptr!=rg->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=rg->SpecialCells(Type, Value);
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
//BOOL AbaoRange::SetComment(void)
//{
//    //CComment &cm=(CComment)rg.get_Comment();
//    try{
//    //LPDISPATCH   lpDisp;//   Often   reused   variable.  
//    //lpDisp   =   rg.get_Comment();
//    if(rg->get_Comment()!=nullptr)
//    {
//        CComment &cm=rg->get_Comment();
//        //cm.AttachDispatch(lpDisp);
//        return TRUE;
//    }
//    else
//    {
//        return FALSE;
//    }
//    }catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//}
//AbaoExcel::AbaoExcel()
//{
//    //this->m_IsAlreadyOpen=FALSE;
//
//}
AbaoExcel::~AbaoExcel()
{
    /*DWORD nErrorNo = GetLastError ( ); // 得到错误代码
    LPSTR lpBuffer;    
    FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER  |
    FORMAT_MESSAGE_IGNORE_INSERTS  |
    FORMAT_MESSAGE_FROM_SYSTEM,
    nullptr,
    nErrorNo, // 此乃错误代码,通常在程序中可由 GetLastError()得之
    LANG_NEUTRAL,
    (LPTSTR) & lpBuffer,
    0 ,
    nullptr );
    CString strErrorCause  =  lpBuffer  ?  _T(lpBuffer) : _T( " Sorry, cannot find this error info. " );
    AfxMessageBox(strErrorCause);*/
}
BOOL AbaoExcel::Add(const CString& ExtPath)
{
    try{
        if(ExtPath.IsEmpty()||ExtPath==_T(""))
        {
            COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
            this->m_preDocsCount=m_unpWorkbooks->get_Count();
            m_unpworkbook->AttachDispatch(m_unpWorkbooks->Add(covOptional));
            this->m_afterDocsCount=m_unpWorkbooks->get_Count();
        }
        else
        {
            this->m_preDocsCount=m_unpWorkbooks->get_Count();
            m_unpworkbook->AttachDispatch(m_unpWorkbooks->Add(_variant_t(ExtPath)));
            this->m_afterDocsCount=m_unpWorkbooks->get_Count();
        }
        m_unpSheets->AttachDispatch(m_unpworkbook->get_Worksheets());
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
const _cUnpEXCELWkS& AbaoExcel::SelectSheet(const CString& SheetName)
{
    try{
        m_unpSheet->AttachDispatch(m_unpSheets->get_Item(COleVariant(SheetName)));//BOOL是微软定义的typedef int BOOL。与bool不同,它是一个三值逻辑,TRUE/FALSE/ERROR,返回值为>0的整数为TRUE,0为FALSE,-1为ERROR
        //m_unpRange->AttachDispatch(m_unpSheet->get_Cells());
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        m_unpSheet->AttachDispatch(nullptr);    
    }
    catch(...)
    {
        m_unpSheet->AttachDispatch(nullptr);
        //    m_unpRange->AttachDispatch(nullptr);
    }
    return m_unpSheet;
}

const _cUnpEXCELWkS& AbaoExcel::SelectSheet(const int &index)//选择一个已知序号的表
{
    try{
        m_unpSheet->AttachDispatch(m_unpSheets->get_Item(_variant_t((long)index)));
        //m_unpRange->AttachDispatch(m_unpSheet->get_Cells(),true);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        m_unpSheet->AttachDispatch(nullptr);    
    }
    catch(...)
    {
        m_unpSheet->AttachDispatch(nullptr);
        //m_unpRange->AttachDispatch(nullptr);
    }
    return m_unpSheet;
}
//BOOL  AbaoExcel::SetCell(const int &row,const int &col,const CString &str)
//{
//    try{
//    m_unpRange->put_Item(_variant_t((long)row),_variant_t((long)col),_variant_t(str));
//    }catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//
//}
//BOOL AbaoExcel::SetCell(const int &row,const int &col,const char* str)
//{
//    try{
//    return SetCell(row,col,CString(str));
//    }catch(...)
//    {
//        return FALSE;
//    }
//
//}
//BOOL AbaoExcel::SetCell(const int &row,const int& col,const long &lv)
//{
//    try{
//    CString t;
//    t.Format(_T("%ld"),lv);
//    return SetCell(row,col,t);
//    }catch(...)
//    {
//        return FALSE;
//    }
//}
//
//
//BOOL AbaoExcel::SetCell(const int& row,const int& col,const double &dv,const int &n)
//{
//    try{
//    CString t;
//    CString format;
//    format.Format(_T("%%.%dlf"),n);
//    t.Format(format,dv);
//    return SetCell(row,col,t);
//    }catch(...)
//    {
//        return FALSE;
//    }
//}
BOOL AbaoExcel::SaveAs(const CString &FileName)
{
    //#define xlExcel9795 43
    try{
        COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
            vFileFormat((short)56);
        //this->m_unpworkbook.SaveCopyAs(COleVariant(FileName));
        //CString tmp=L"";
        if(this->m_unpApp->get_Version()==L"11.0")
        {
            //tmp.Format(L"%s  before SaveCopyAs",FileName);
            //::AfxMessageBox(tmp);
            this->m_unpworkbook->SaveCopyAs(COleVariant(FileName));
            //::AfxMessageBox(L"after SaveCopyAs");
        }
        else{
            //        tmp.Format(L"%s  before SaveAs",FileName);
            //::AfxMessageBox(tmp);
            this->m_unpworkbook->SaveAs(COleVariant(FileName),vFileFormat,covOptional,covOptional,covOptional,covOptional,1,covOptional,covOptional,covOptional,covOptional,covOptional);
            //::AfxMessageBox(L"after SaveAs");
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::SaveAs2(const CString &FileName)
{
    //#define xlExcel9795 43
    try{
        COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR),
            vFileFormat((short)56),vFileFormat2((short)-4143);
        //this->m_unpworkbook.Save();
        if(this->m_unpApp->get_Version()==L"11.0")
        {
            this->m_unpworkbook->SaveAs(COleVariant(FileName),vFileFormat2,covOptional,covOptional,covOptional,covOptional,1,covOptional,covOptional,covOptional,covOptional,covOptional);
        }
        else{
            this->m_unpworkbook->SaveAs(COleVariant(FileName),vFileFormat,covOptional,covOptional,covOptional,covOptional,1,covOptional,covOptional,covOptional,covOptional,covOptional);
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::CopySheet(LPDISPATCH sht)
{
    try{
        m_unpSheet->Copy(vtMissing,_variant_t(sht));
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
//void AbaoExcel::SetALLCommentFontSize(short sizeValue)
//{
//    m_unpCms.AttachDispatch(m_unpSheet.get_Comments());
//    int cmsCount=m_unpCms.get_Count();
//    CComment  m_unptmpComment;
//    CShape  tmpSp;
//        CTextFrame tmpTf;
//        CCharacters tmpCh;
//        CFont0 tmpFt;
//    for(int i=1;i<=cmsCount;i++)
//    {
//        m_unptmpComment.AttachDispatch(m_unpCms.Item(i));
//        //    LPDISPATCH   lpDisp;//   Often   reused   variable.  
//    //lpDisp   =   cm.get_Shape();
//    tmpSp.AttachDispatch(m_unptmpComment.get_Shape());
//    
//    //sp.put_Width(276);
//    lpDisp = tmpSp.get_TextFrame();
//    tmpTf.AttachDispatch(tmpSp.get_TextFrame());
//    
//    //tf.put_MarginBottom(2);
//    //tf.put_AutoSize(true);
//    //tf.put_AutoMargins(true);
//    COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//    //lpDisp = tmpTf.Characters(covOptional,covOptional);
//    tmpCh.AttachDispatch(tmpTf.Characters(covOptional,covOptional));
//    lpDisp = tmpCh.get_Font();
//    //int len=ch.get_Count();
//    //sp.put_Height((len/26+1)*18);
//    tmpFt.AttachDispatch(tmpCh.get_Font());
//    //static long TimeSum2=0;
//    COleVariant vSize((short)sizeValue);
//    tmpFt.put_Size(vSize);
//    tmpTf.put_AutoSize(true);
//    }
//}
LPDISPATCH AbaoExcel::GetRange(const CString &RangeStart,const CString &RangeEnd)
{
    LPDISPATCH lpDisp=nullptr;
    try{
        if(nullptr!=m_unpSheet->m_lpDispatch)
        {//unpRange.reset(new CRange);
            lpDisp=m_unpSheet->get_Range(COleVariant(RangeStart),COleVariant(RangeEnd));    
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;    
    }
    catch(...)
    {
        ::AfxMessageBox(_T("AbaoExcel::GetRange失败!"));
        return nullptr;
    }
    return lpDisp;
}//获取m_unpRange,
LPDISPATCH AbaoExcel::GetRange2(const CString& RangeStart)
{
    //return m_unpSheet.get_Range(COleVariant(RangeStart),COleVariant(RangeStart));
    LPDISPATCH lpDisp=nullptr;
    try{

        if(nullptr!=m_unpSheet->m_lpDispatch)
        {
            //unpRange.reset(new CRange);
            lpDisp=m_unpSheet->get_Range(COleVariant(RangeStart),COleVariant(RangeStart));    
        }

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;    
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
    //return m_unpRange;
}//获取m_unpRange,
LPDISPATCH AbaoExcel::GetRange(const CString& RangeStr)
{
    int pos=RangeStr.Find(':');
    if(pos>0)
    {
        CString a,b;
        a=RangeStr.Left(pos);
        b=RangeStr.Right(RangeStr.GetLength()-pos-1);
        return GetRange(a,b);
    }
    else
    {
        return GetRange(RangeStr,RangeStr);
    }
}//获取m_unpRange A1:A2模式
LPDISPATCH AbaoExcel::get_UsedRange(void)
{
    LPDISPATCH lpDisp=nullptr;
    try{

        if(nullptr!=m_unpSheet->m_lpDispatch)
        {
            //unpRange.reset(new CRange);
            lpDisp=m_unpSheet->get_UsedRange();    
        }

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;    
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
LPDISPATCH AbaoExcel::get_Comments(void)
{
    LPDISPATCH lpDisp=nullptr;
    try{

        if(nullptr!=m_unpSheet->m_lpDispatch)
        {
            //unpRange.reset(new CRange);
            lpDisp=m_unpSheet->get_Comments();    
        }

    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;    
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
CString AbaoExcel::get_SheetName()
{
    CString tmpStr;
    try{
        tmpStr=m_unpSheet->get_Name();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return tmpStr;    
    }
    catch(...)
    {
        return tmpStr;////nullptr,BSTR)
    }
    return tmpStr;
}
BOOL AbaoExcel::put_SheetName(LPCTSTR newValue)
{
    try{
        m_unpSheet->put_Name(newValue);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
LPDISPATCH AbaoExcel::ActiveSheetRange()
{
    LPDISPATCH lpDisp=nullptr;
    try{
        //unpRange.reset(new CRange);
        lpDisp=m_unpSheet->get_Cells();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;    
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
BOOL AbaoExcel::put_Saved(BOOL bFlag)
{
    try{
        m_unpworkbook->put_Saved(bFlag);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
//BOOL AbaoExcel::MergeRange(const CString& RangeStr)
//{
//    try{
//    GetRange(RangeStr)->Merge(COleVariant(long(1)));
//    }catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//}//合并Range
LPDISPATCH AbaoExcel::ActiveSheet()
{
    LPDISPATCH lpDisp=nullptr;
    try{
        lpDisp=m_unpSheet->m_lpDispatch;
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return nullptr;    
    }
    catch(...)
    {
        return nullptr;
    }
    return lpDisp;
}
BOOL AbaoExcel::put_AutoFilterMode(BOOL bFlag)
{
    try{
        m_unpSheet->put_AutoFilterMode(bFlag);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::Protect(VARIANT& Password, VARIANT& DrawingObjects, VARIANT& Contents, VARIANT& Scenarios, VARIANT& UserInterfaceOnly, VARIANT& AllowFormattingCells, VARIANT& AllowFormattingColumns, VARIANT& AllowFormattingRows, VARIANT& AllowInsertingColumns, VARIANT& AllowInsertingRows, VARIANT& AllowInsertingHyperlinks, VARIANT& AllowDeletingColumns, VARIANT& AllowDeletingRows, VARIANT& AllowSorting, VARIANT& AllowFiltering, VARIANT& AllowUsingPivotTables)
{
    try{
        m_unpSheet->Protect(Password, DrawingObjects, Contents, Scenarios, UserInterfaceOnly, AllowFormattingCells, AllowFormattingColumns,  AllowFormattingRows,AllowInsertingColumns,AllowInsertingRows,AllowInsertingHyperlinks, AllowDeletingColumns, AllowDeletingRows,  AllowSorting,AllowFiltering, AllowUsingPivotTables);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::Unprotect(VARIANT& Password)
{
    try{
        m_unpSheet->Unprotect(Password);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
int AbaoExcel::get_SheetCount(void)
{
    int iRet;
    try{
        iRet=this->m_unpSheets->get_Count();
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return -1;    
    }
    catch(...)
    {
        return -1;
    }
    return iRet;
}
BOOL AbaoExcel::open(const CString &Filename)//
{
    try{
        COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        COleVariant vTrue((short)TRUE);
        if(m_unpWorkbooks->m_lpDispatch==nullptr)
        {
            ::AfxMessageBox(_T("m_unpworkbook打开失败,请先打开workbooks!"));
            return FALSE;
        }
        
        if(m_unpworkbook->m_lpDispatch!=nullptr)
        {
            if(FALSE==CloseWorkBook())//保证一个对象只打开一个workbook
                return FALSE;
        }
        //m_unpworkbook.reset(new CWorkbook);
        this->m_preDocsCount=m_unpWorkbooks->get_Count();
        //if(m_unpworkbook->get_IsInplace()==FALSE)
        //{
        //    return FALSE;
        //}
        m_unpworkbook->AttachDispatch(m_unpWorkbooks->_Open(Filename, VOptional, vTrue, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional));  
        //BOOL flag=m_unpworkbook->get_IsInplace();

        this->m_afterDocsCount=m_unpWorkbooks->get_Count();
        //m_unpSheets.reset(new CWorksheets);
        m_unpSheets->AttachDispatch(m_unpworkbook->get_Worksheets(),true);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::openAllowWrite(const CString &Filename)//
{
    try{
        COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        COleVariant vFALSE((short)FALSE);
        if(m_unpWorkbooks->m_lpDispatch==nullptr)
        {
            ::AfxMessageBox(_T("m_unpworkbook打开失败,请先打开workbooks!"));
            return FALSE;
        }
        
        if(m_unpworkbook->m_lpDispatch!=nullptr)
        {
            if(FALSE==CloseWorkBook())//保证一个对象只打开一个workbook
                return FALSE;
        }
        //m_unpworkbook.reset(new CWorkbook);
        this->m_preDocsCount=m_unpWorkbooks->get_Count();
        m_unpworkbook->AttachDispatch(m_unpWorkbooks->_Open(Filename, VOptional, vFALSE, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional));  
        BOOL flag=m_unpworkbook->get_IsInplace();
        this->m_afterDocsCount=m_unpWorkbooks->get_Count();
        //m_unpSheets.reset(new CWorksheets);
        m_unpSheets->AttachDispatch(m_unpworkbook->get_Worksheets(),true);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::CloseWorkBook(void)
{
    try{
        COleVariant vTrue((short)TRUE),    
            vFalse((short)FALSE),
            vOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
        if (m_unpworkbook->m_lpDispatch==nullptr)
        {
            //AfxMessageBox(_T("Document获取失败!"), MB_OK|MB_ICONWARNING);
            return FALSE;
        }
        if(this->m_afterDocsCount==this->m_preDocsCount+1)
        {
            m_unpworkbook->Close(vFalse,    // SaveChanges.
                vFalse,            // OriginalFormat.
                vFalse            // RouteDocument.
                );
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
        catch(COleException   *e)   
        {   

            TCHAR buf[1024];           //   For   the   Try...Catch   error   message.   
            swprintf(buf,sizeof(buf),_T("COleException.   SCODE:   %08lx."),   (long)e->m_sc);   
            ::MessageBox(NULL,   buf,   _T("COleException"),   MB_SETFOREGROUND   |   MB_OK);   
            //::PostMessage(m_pDialogProgress2->m_hWnd,MY_MACRO_WM_USER_THREAD_FINISHED,0,0);
            //CloseHandle(m_pDialogProgress2->m_hEventModelDlgCreated);
            //a2.CloseWorkBook(TaiZhangExcelFile2);
            //a2.CloseWorkBook(strTaiZhangPath);
            //a2.CloseApp();
            return FALSE;
        }   
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL AbaoExcel::CreateApp()
{
    CLSID clsid;
    HRESULT hr;
    try{
        hr=::CLSIDFromProgID(L"Excel.Application",&clsid);    //通过ProgID取得CLSID
        if(FAILED(hr))
        {
            AfxMessageBox(_T("没有安装OFFICE"));
            return FALSE;
        }

        IUnknown *pUnknown=nullptr;
        //IDispatch *pDispatch=nullptr;

        hr=::GetActiveObject(clsid,nullptr,&pUnknown);    //查找是否有WORD程序在运行
        if(FAILED(hr))                                // 没有正在运行的,则启动新应用
        {
            if (FALSE == m_unpApp->CreateDispatch(_T("Excel.Application")))
            {
                AfxMessageBox(_T("Application创建失败,请确保安装了excel 2000或以上版本!"), MB_OK|MB_ICONWARNING);
                return FALSE;
            }
            m_bIsNewApp = TRUE;
            m_unpWorkbooks->AttachDispatch(m_unpApp->get_Workbooks());
        }
        else{
            hr=pUnknown->QueryInterface(IID_IDispatch,(LPVOID *)m_unpApp.get());
            if(FAILED(hr))    {::AfxMessageBox(_T("没有取得IDispatchPtr")); return FALSE;}
            pUnknown->Release();    pUnknown=nullptr;
            m_bIsNewApp = FALSE;    
            m_unpWorkbooks->AttachDispatch(m_unpApp->get_Workbooks(),true);

        }
    m_unpApp->put_Visible(FALSE);
    m_unpApp->put_DisplayAlerts(FALSE);
    m_unpApp->put_ScreenUpdating(FALSE);
    m_unpApp->put_EnableEvents(FALSE);
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }

    return TRUE;
}
//BOOL AbaoExcel::put_DisplayAlerts(BOOL bFlag)
//{
//    try{
//        this->m_unpApp->put_DisplayAlerts(bFlag);
//    }
//    catch(_com_error &e)
//    {
//        dump_com_error(e);
//        return FALSE;    
//    }
//    catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//}
//BOOL AbaoExcel::put_ScreenUpdating(BOOL bFlag)
//{
//    try{
//        this->m_unpApp->put_ScreenUpdating(bFlag);
//    }
//    catch(_com_error &e)
//    {
//        dump_com_error(e);
//        return FALSE;    
//    }
//    catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//}
//BOOL AbaoExcel::put_EnableEvents(BOOL bFlag)
//{
//    try{
//        this->m_unpApp->put_EnableEvents(bFlag);
//    }
//    catch(_com_error &e)
//    {
//        dump_com_error(e);
//        return FALSE;    
//    }
//    catch(...)
//    {
//        return FALSE;
//    }
//    return TRUE;
//}
BOOL AbaoExcel::CloseApp()
{
    try{
        if (m_bIsNewApp == TRUE)
        {
            m_unpWorkbooks->Close();
            m_unpApp->Quit();

        }
        else
        {
    m_unpApp->put_Visible(TRUE);
    m_unpApp->put_DisplayAlerts(TRUE);
    m_unpApp->put_ScreenUpdating(TRUE);
    m_unpApp->put_EnableEvents(TRUE);
        }
    }
    catch(_com_error &e)
    {
        dump_com_error(e);
        return FALSE;    
    }
    catch(...)
    {
        return FALSE;
    }
    return TRUE;
}

aboExcel.cpp文件完。

_cMyExcel.h内容:这个文件是本人用的,因为不好说与我原来的版本有什么出入,所以还是贴出来让大家一起参考。

#ifndef _abaoExcel_h_

/************************************
REVISION LOG ENTRY
Revision By: abao++
Revised on 2006-8-11 8:13:07
Comments: ...
看了无数关于vc调用excel的贴,可是都是原始的方法,用起来一个字,不方便
为了做一个项目,特封装了一个类,功能那是非常之。。。。。。。。。。弱弱的。
不过一般简单的excel文档可以搞定了。而且,这个是可以扩展,可以继承的,,继承就免了吧,
改一下俺不会告你侵权的,不过最好不要擦除俺的功劳,虽然俺只写了几个简单函数

调用前请确保已经调用了如下函数初始化com库,

if (CoInitialize(NULL)!=0)
{
AfxMessageBox("初始化COM支持库失败!");
exit(1);
}
************************************/

#define _abaoExcel_h_

#include <comdef.h>
#include "capplication.h"
#include "CBorder.h"
#include "CBorders.h"
#include "CRange.h"
#include "CRanges.h"
#include "cworkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "CComment.h"
#include "CComments.h"
#include "CShape.h"
#include "CTextFrame.h"
//#include "cwindow1.h"
//#include "cwindows.h"
//#include "CCharacters.h"
#include "CFont0.h"
#include <memory>
#include <functional>
#include "ado.h"
enum RangeHAlignment{HAlignDefault=1,HAlignCenter=-4108,HAlignLeft=-4131,HAlignRight=-4152};
enum RangeVAlignment{VAlignDefault=2,VAlignCenter=-4108,VAlignTop=-4160,VAlignBottom=-4107};
class _cEXCELMemberDeleter{
    // What should be the default?? No deleter? delete? I choose to
    // mimic the default of unique_ptr.
public:
    _cEXCELMemberDeleter(): f([](COleDispatchDriver *p){
        if(NULL!=p){
            if(NULL!=p->m_lpDispatch)
            p->ReleaseDispatch();
            delete p;
        }
    })
        {};
        // allow the user to specify what type of deleter to use
        explicit _cEXCELMemberDeleter(std::tr1::function< void(COleDispatchDriver *)> const &f_ )
            : f(f_)
        {};

        void operator()(COleDispatchDriver *p) const
        {
            f(p);
        };

private:
    std::tr1::function< void(COleDispatchDriver *)> f;
};

//typedef _cEXCELMemberDeleter<CRange> _cEXCEL_DelRg;
//typedef _cEXCELMemberDeleter<CBorder> _cEXCEL_DelBd;
//typedef _cEXCELMemberDeleter<CComment> _cEXCEL_DelCm;
//typedef _cEXCELMemberDeleter<CShape> _cEXCEL_DelSp;
//typedef _cEXCELMemberDeleter<CTextFrame> _cEXCEL_DelTF;
//typedef _cEXCELMemberDeleter<CFont0> _cEXCEL_DelFt0;

typedef std::unique_ptr<CRange,_cEXCELMemberDeleter> _cUnpEXCELRg;
typedef std::unique_ptr<CBorders,_cEXCELMemberDeleter> _cUnpEXCELBds;
typedef std::unique_ptr<CBorder,_cEXCELMemberDeleter> _cUnpEXCELBd;
typedef std::unique_ptr<CComments,_cEXCELMemberDeleter> _cUnpEXCELCms;
typedef std::unique_ptr<CComment,_cEXCELMemberDeleter> _cUnpEXCELCm;
typedef std::unique_ptr<CShape,_cEXCELMemberDeleter> _cUnpEXCELSp;
typedef std::unique_ptr<CTextFrame,_cEXCELMemberDeleter> _cUnpEXCELTF;
typedef std::unique_ptr<CFont0,_cEXCELMemberDeleter> _cUnpEXCELFt0;
class AbaoComments
{
private:
    //bool _isNull;
    const _cUnpEXCELCms cms;
    //const _cUnpEXCELRg funInit(const _cUnpEXCELRg& m_unpRange);
    //static const _cUnpEXCELRg& rgNULL;
    //static const _cUnpEXCELRg& rgNomal;
public:

    
    ~AbaoComments();
     //operator AbaoRange*() { return _isNull ? nullptr : this; }
    AbaoComments();
    AbaoComments& operator=(LPDISPATCH&& disComments);
    LPUNKNOWN get__NewEnum(void);
    int get_Count(void);
};
class AbaoComment
{
private:
    //bool _isNull;
    const _cUnpEXCELCm cm;
    //const _cUnpEXCELRg funInit(const _cUnpEXCELRg& m_unpRange);
    //static const _cUnpEXCELRg& rgNULL;
    //static const _cUnpEXCELRg& rgNomal;
public:

    
    ~AbaoComment();
     //operator AbaoRange*() { return _isNull ? nullptr : this; }
    AbaoComment();
    AbaoComment& operator=(LPDISPATCH&& unpComment);//赋值另一个unpComment
    
    CString Text(VARIANT& Text, VARIANT& Start, VARIANT& Overwrite);
};
class AbaoRange
{
private:
    //bool _isNull;
    const _cUnpEXCELRg rg;
    //const _cUnpEXCELRg funInit(const _cUnpEXCELRg& m_unpRange);
    //static const _cUnpEXCELRg& rgNULL;
    //static const _cUnpEXCELRg& rgNomal;
public:

    
    ~AbaoRange();
     //operator AbaoRange*() { return _isNull ? nullptr : this; }
    AbaoRange();
    BOOL Copy();
    BOOL Paste();
    BOOL Merge();//合并
    BOOL Delete(long Xlconst);
    BOOL IsValid();
    const AbaoRange& operator=(const CString& s); //填入一个s,,
    const AbaoRange& operator=(const TCHAR* str);//填入char*
    AbaoRange& operator=(LPDISPATCH&& unpRange);//赋值另一个m_unpRange
    LPDISPATCH GetComment(void);
    BOOL Border(const short &mode=1,const long &BoderWidth=1,const long &ColorIndex=1, VARIANT &color=COleVariant((long)DISP_E_PARAMNOTFOUND,VT_ERROR));
    //设置边框,参数我还没有弄清楚
    BOOL BorderALL(const short &mode=1,const long &BoderWidth=1,const long &ColorIndex=1,VARIANT &color=COleVariant((long)DISP_E_PARAMNOTFOUND,VT_ERROR));
    ////BOOL SetHAlign(RangeHAlignment mode=HAlignDefault);
    //////设置对齐方式
    ////BOOL SetVAlign(RangeVAlignment mode=VAlignDefault);
    BOOL SetNumberFormat(const CString& s);
    LPDISPATCH get_Rows(void);
    LPDISPATCH get_Columns(void);
    BOOL Select();
    BOOL Locked(bool bIsLocked);
    long get_Count(void);
long get_Column();
long get_Row();
BOOL put_RowHeight(VARIANT& newValue);
BOOL put_ColumnWidth(VARIANT& newValue);
BOOL Delete_Duplicate(VARIANT& Column,long Header);
BOOL CopyFrRs(unique_ptr<CADORecordset>& rs,const long& MaxRows,const long& MaxCol);
    VARIANT TextToColumns(VARIANT& Destination, long DataType, long TextQualifier, VARIANT& ConsecutiveDelimiter, VARIANT& Tab, VARIANT& Semicolon, VARIANT& Comma, VARIANT& Space, VARIANT& Other, VARIANT& OtherChar, VARIANT& FieldInfo, VARIANT& DecimalSeparator, VARIANT& ThousandsSeparator, VARIANT& TrailingMinusNumbers);
    LPDISPATCH SpecialCells(long Type, VARIANT& Value);
    BOOL ClearComments();
    VARIANT get_Text(void);
    VARIANT get_Formula(void);
    BOOL put_Formula(VARIANT& newValue);
BOOL put_Value2(VARIANT& newValue);
VARIANT get_Value2(void);
    LPDISPATCH Find(VARIANT& What, VARIANT& After, VARIANT& LookIn, VARIANT& LookAt, VARIANT& SearchOrder, long SearchDirection, VARIANT& MatchCase, VARIANT& MatchByte, VARIANT& SearchFormat);
    //LPDISPATCH  SetComment2(void);
    //BOOL SetComment(void);
    //BOOL SetCommentFontSize(short sizeValue);
    //BOOL autosize(void);
    //设置竖直对齐
};

//std::unique_ptr用于独占指针对象,并保证指针所指对象生命周期与其一致
//使得对象能及时析构,提升程序性能。
typedef std::unique_ptr<CApplication,_cEXCELMemberDeleter> _cUnpEXCELApp;
typedef std::unique_ptr<CWorkbooks,_cEXCELMemberDeleter> _cUnpEXCELWkBs;
typedef std::unique_ptr<CWorkbook,_cEXCELMemberDeleter> _cUnpEXCELWkB;
typedef std::unique_ptr<CWorksheets,_cEXCELMemberDeleter> _cUnpEXCELWkSs;
typedef std::unique_ptr<CWorksheet,_cEXCELMemberDeleter> _cUnpEXCELWkS;
typedef std::unique_ptr<CComments,_cEXCELMemberDeleter> _cUnpEXCELCms;


//Excel对象类,通过微软Excel提供的Excel API对Excel文档进行操作
class _cMyExcel
{

public:
    //不使用裸指针的原因是为了
    //可以使得指针析构时,所拥有的对象也跟着析构
    //减少了对成员对象析构和内存可能泄漏的关注。
    //如果用了裸指针,那么它所指向的对象有可能没有被析构,产生内存泄漏

    //那么为什么不直接定义Excel相关对象的成员呢,
    //因为如果定义了相关成员,那么在_cMyExcel对象存在的期间
    //成员都存在,有可能浪费内存资源。当然在这里不存在这个区别
    //,因为_cMyExcel对象在构造同时用new构造了相关Excel对象。

    //用const的原因是为了保证,指针成员只能在构造中被赋值,
    //减少了可能在编程过程中,错误的再一次给它赋值.
    //收紧了对该类的使用限制,避免不必要的意外错误的发生。
    //建议将对象限制为由一个所有者所有,因为多个所有权会使程序逻辑变得复杂。
    const _cUnpEXCELApp m_unpApp; //excep
    const _cUnpEXCELWkBs m_unpWorkbooks; //m_unpWorkbooks
    const _cUnpEXCELWkB m_unpworkbook; //m_unpworkbook
    const _cUnpEXCELWkSs m_unpSheets; //m_unpSheet
    const _cUnpEXCELWkS m_unpSheet; //当前的表 ,可以通过SelectSheet 来改变
    //const _cUnpEXCELRg m_unpRange;
    //_cUnpEXCELWkS m_unptmpSheet; //当前的表 ,可以通过SelectSheet 来改变
    
    //const _cUnpEXCELCms m_unpCms;
    //const _cUnpEXCELCm  m_unptmpComment;
    //std::unique_ptr<CWorkbooks> m_unpWorkbooks; //m_unpWorkbooks
    //std::unique_ptr<CWorkbook> m_unpworkbook; //m_unpworkbook
    //std::unique_ptr<CWorksheets> m_unpSheets; //m_unpSheet
    //std::unique_ptr<CWorksheet> m_unpSheet; //当前的表 ,可以通过SelectSheet 来改变
    ////CWorksheet tmpSheet; //当前的表 ,可以通过SelectSheet 来改变
    //std::unique_ptr<CRange> m_unpRange; //m_unpRange
    //std::unique_ptr<CComments> m_unpCms;
    //std::unique_ptr<CComment>  m_unptmpComment;
    BOOL   m_bIsNewApp;
    long   m_preDocsCount;
    long   m_afterDocsCount;
    bool   m_IsFirst;
    _cMyExcel(LPDISPATCH appDisp);
    //LPDISPATCH lpDisp;    // Often reused variable.
    _cMyExcel(bool IsFirst=false):m_unpApp(new CApplication),m_unpWorkbooks(new CWorkbooks)
    ,m_unpworkbook(new CWorkbook),m_unpSheets(new CWorksheets)
    ,m_unpSheet(new CWorksheet),m_IsFirst(IsFirst){
        //m_unpworkbook->m_lpDispatch=NULL;
        //m_unpSheets->m_lpDispatch=NULL;
        //m_unpSheet->m_lpDispatch=NULL;
    };
    //  MyClass() : factory ( unique_ptr<ClassFactory>(new ClassFactory()))
    ~_cMyExcel();
    BOOL CreateApp(void);
    BOOL CreateNewApp();
    BOOL CloseApp(void);
    BOOL CloseNewApp(void);
    BOOL put_DisplayAlerts(BOOL bFlag);
    BOOL put_ScreenUpdating(BOOL bFlag);
    BOOL put_EnableEvents(BOOL bFlag);
    BOOL CloseWorkBook(void);
    BOOL open(const CString &Filename);
    BOOL openXml(const CString &Filename);
    BOOL openAllowWrite(const CString &Filename);
BOOL openXML(const CString &Filename);//
    bool IsXlsOpen(const CString &strFileName);
    LPDISPATCH ActiveSheet();//当前活动的m_unpSheet,在SelectSheet 后改变

    BOOL Add(const CString& ExtPath=CString(""));//从一个模版构造
    const _cUnpEXCELWkS& SelectSheet(const CString& SheetName);//选择一个已知表名的表
    const _cUnpEXCELWkS& SelectSheet(const char* SheetName){return SelectSheet(CString(SheetName));};//选择一个已知表名的表
    const _cUnpEXCELWkS& SelectSheet(const int &index);//选择一个已知表名的表
    BOOL SetALLCommentFontSize(const short &sizeValue);
    //BOOL SetCell(const int &row,const int &col,const CString &str);//指定行列的单元格填入值
    //BOOL SetCell(const int &row,const int &col,const char* str);//指定行列的单元格填入值
    //BOOL SetCell(const int &row,const int &col,const long &lv);//指定行列填入long值
    //BOOL SetCell(const int &row,const int &col,const double &dv,const int& n=6);//指定行列填入浮点值,并截取为指定的小数位
    LPDISPATCH GetRange(const CString &RangeStart,const CString &RangeEnd);//获取m_unpRange,
    LPDISPATCH GetRange2(const CString &RangeStart);//获取m_unpRange,
    LPDISPATCH GetRange(const CString &RangeStr);//获取m_unpRange A1:A2模式
    LPDISPATCH get_UsedRange(void);
    LPDISPATCH ActiveSheetRange(void);//当前的m_unpRange,在使用GetRange后改变
    LPDISPATCH get_Comments(void);
    //BOOL MergeRange(const CString& RangeStr);//合并Range
    BOOL put_Saved(BOOL bFlag);
    BOOL put_AutoFilterMode(BOOL bFlag);
    BOOL Protect(VARIANT& Password, VARIANT& DrawingObjects, VARIANT& Contents, VARIANT& Scenarios, VARIANT& UserInterfaceOnly, VARIANT& AllowFormattingCells, VARIANT& AllowFormattingColumns, VARIANT& AllowFormattingRows, VARIANT& AllowInsertingColumns, VARIANT& AllowInsertingRows, VARIANT& AllowInsertingHyperlinks, VARIANT& AllowDeletingColumns, VARIANT& AllowDeletingRows, VARIANT& AllowSorting, VARIANT& AllowFiltering, VARIANT& AllowUsingPivotTables);
    BOOL Unprotect(VARIANT& Password);
    int get_SheetCount(void);
    CString get_SheetName(void);
    BOOL put_SheetName(LPCTSTR newValue);
    BOOL AddMultiSheets(int Sheetcount,bool IsAfter,CString & TemplatefullPath);
//BOOL RenameWorkbook(const CString &strFileName);
    //int SetVisible(bool visible) {m_unpApp->put_Visible(visible);return 1;}//设置为可见以及隐藏
    BOOL SaveAs(const CString &FileName);//保存到文件名
    BOOL SaveAs_ConvertNormXls(const CString &FileName);
    BOOL SaveAsTemplate(const CString &FileName);
    BOOL CopySheet(LPDISPATCH sht);//复制一个m_unpSheet
    HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...);
};
class _cEXCELWrapDeleter{
    // What should be the default?? No deleter? delete? I choose to
    // mimic the default of unique_ptr.
public:
    _cEXCELWrapDeleter(): f([](_cMyExcel *p){
        if(NULL!=p){
            if(NULL!=p->m_unpworkbook->m_lpDispatch)
                p->CloseWorkBook();
            if(NULL!=p->m_unpApp->m_lpDispatch)
                p->CloseApp();
            delete p;}})
        {};
        // allow the user to specify what type of deleter to use
        explicit _cEXCELWrapDeleter(std::tr1::function< void(_cMyExcel *)> const &f_ )
            : f(f_)
        {};

        void operator()(_cMyExcel *p) const
        {
            f(p);
        };

private:
    std::tr1::function< void(_cMyExcel *)> f;
};
typedef std::unique_ptr<_cMyExcel,_cEXCELWrapDeleter> _cUnpAbaoExcel;
#endif

完。

不用感谢我,因为我是雷锋。

猜你喜欢

转载自blog.csdn.net/tom_xuzg/article/details/81603532
今日推荐