合并多个Excel文件

       前段时间匆匆忙忙写的一个小总结,贴出来请大家指点一下,有什么不好的请指点一下,在编程上我基本上是乱模仿出家,没有受过什么系统的培训。

     上个周也就是元旦过后的第一个周,匆匆忙忙的为公司客服部做了一个Excel合并软件。主要功能是:对多个Excel文件,按照对应Sheet和其中对应的列进行合并,也就是说合并的文件Sheet数目以及每一个对应Sheet的对应列名必须相同,如果不相同则不合并。由于时间紧迫,并且上班期间公司不能上外网,害得我只能晚上回家搜集资料,白天在公司再仔细研究,通过查找资料,发现很多人是对Excel中的每一个元素进行处理的,并且有现成的代码可用,我也就用这种方法进行处理了。具体方法是对每一个Excel文件中的每一个Sheet中的每一个元素进行拷贝。由于合并时间比较长,我采用创建一个线程显示进度条并进行合并处理的方法。


主要代码如下:
/*===========================================================================
函 数 名:        FileCvtThread
功能描述:        文件合并线程
输入参数:        CProgressDlg *pThisObj     进度条的指针
输出参数:        None
返回值  :        void
创建日期:        2008-1-5
修改日期:       
作    者:        zcd
附加说明:        文件合并过程中,同时进行进度条位置的控制。
-----------------------------------------------------------------------       
历史:               
修改时间                                修改人                                修改内容                                                                                                       
2008-1-5                                zcd                                创建该函数       

========================================================================*/
void CProgressDlg::FileCvtThread(CProgressDlg *pThisObj)
{
        //设置初始化时进度条的位置及文本
        pThisObj->m_progress.SetPos(pThisObj->m_pro);
        pThisObj->m_progress.SetText(pThisObj->m_strContent);
       
        //初始化COM控件
        if (CoInitialize(NULL)!=0)
        {
                AfxMessageBox("初始化COM支持库失败!");
                exit(1);
        }

        //声明目的文件用到变量
        _Application   app;          
        Workbooks   books;  
        _Workbook   book;  
        Worksheets   sheets;  
        _Worksheet   sheet;  
        Range   range;  
        Range   iCell;  
        LPDISPATCH   lpDisp;          
        COleVariant   vResult;  
        COleVariant  
                covTrue((short)TRUE),  
                covFalse((short)FALSE),  
                covOptional((long)DISP_E_PARAMNOTFOUND,   VT_ERROR);

        //创建Excel   2000服务器(启动Excel) 
        if(!app.CreateDispatch("Excel.Application"))    
        {  
                AfxMessageBox("无法启动Excel服务器!");  
                return;  
        }  

        app.SetVisible(FALSE);              //使Excel可见  
        app.SetUserControl(TRUE);          //允许其它用户控制Excel  

        //打开目的文件  
        books.AttachDispatch(app.GetWorkbooks());  

        //声明源文件用到的变量
        LPDISPATCH   lpDispSour;
        _Workbook   bookSour;  
        Worksheets   sheetsSour;  
        _Worksheet   sheetSour;  
        Range   rangeSour;  
        Range   iCellSour;

        //*****
        //打开目的文件
        lpDisp   =   books.Open(pThisObj->m_strDest,              
                covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
                covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
                covOptional,   covOptional   );  

        //*****  
        //得到Workbook  
        book.AttachDispatch(lpDisp);  

        //*****  
        //得到Worksheets    
        sheets.AttachDispatch(book.GetWorksheets());    

        //得到一个文件中有几个Sheet
        long items = sheets.GetCount();

        //*****  
        //得到当前活跃sheet  
        //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待  
        lpDisp=book.GetActiveSheet();  

        //得到几个源文件
        int count = static_cast<int>(pThisObj->m_strArrSour.GetCount());

        for (int i = 0; i < count;i++)
        {
                //打开源文件
                lpDispSour   =   books.Open(pThisObj->m_strArrSour[i].GetString(),              
                        covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
                        covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
                        covOptional,   covOptional   );  
               
                //得到Workbook  
                bookSour.AttachDispatch(lpDispSour);  


                //*****  
                //得到Worksheets    
                sheetsSour.AttachDispatch(bookSour.GetWorksheets());    
                //*****  

                //*****  
                //得到当前活跃sheet  
                //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待  
                lpDispSour=bookSour.GetActiveSheet(); 

                //对每张表做循环拷贝
                do
                {
                        //设置开始合并时进度条的位置及文本
                        pThisObj->m_progress.SetPos(pThisObj->m_pro);
                        CString strout;
                        strout.Format("正在合并文件:%s,总共已完成%d%%",pThisObj->m_strArrName[i].GetString(),pThisObj->pro);//
                        pThisObj->m_progress.SetText(strout);
                       
                        //得到目的文件的Worksheets
                        sheet.AttachDispatch(lpDisp);    

                        //*****  
                        //读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列  
                        Range   usedRange;  
                        usedRange.AttachDispatch(sheet.GetUsedRange());
                        range.AttachDispatch(usedRange.GetRows());  
                        long   iRowNum=range.GetCount();          //已经使用的行数  

                        range.AttachDispatch(usedRange.GetColumns());  
                        long   iColNum=range.GetCount();   //已经使用的列数

                        //得到源Excel文件的Worksheets
                        sheetSour.AttachDispatch(lpDispSour);    

                        //*****  
                        //读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列  
                        Range   usedRangeSour;  
                        usedRangeSour.AttachDispatch(sheetSour.GetUsedRange()); 
                        rangeSour.AttachDispatch(usedRangeSour.GetRows());  
                        long   iRowNumSour=rangeSour.GetCount();                                       //已经使用的行数  

                        rangeSour.AttachDispatch(usedRangeSour.GetColumns());  
                        long   iColNumSour=rangeSour.GetCount();   //已经使用的列数 
                       
                        //判断目的文件与源文件的列数是否相同
                        if (iColNum != iColNumSour)
                        {
                                char  buffer[200];
                                sprintf(buffer,(const char*)"源文件与目的文件在表: %s 中的列数不同",sheet.GetName());
                                AfxMessageBox(buffer);
                                return;
                        }
                        //获取目的Range  
                        range.AttachDispatch(sheet.GetCells());    

                        //*****  
                        //获取源Range
                        rangeSour.AttachDispatch(sheetSour.GetCells()); 

                        //判断每一列的列名称是否相同,不相同则返回
                        for (long j = 2; j <= iColNumSour; j++)
                        {
                                iCell.AttachDispatch((range.GetItem(COleVariant(long(2)),   COleVariant(long(j)))).pdispVal);  
                                vResult = iCell.GetText();
                                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="";  
                                } 

                                iCellSour.AttachDispatch((rangeSour.GetItem(COleVariant(long(2)),   COleVariant(long(j)))).pdispVal);  
                                vResult = iCellSour.GetText();

                                CString   strSour;  
                                if(vResult.vt   ==   VT_BSTR)               //字符串  
                                {  
                                        strSour=vResult.bstrVal;  
                                }  
                                else   if   (vResult.vt==VT_R8)           //8字节的数字    
                                {  
                                        strSour.Format("%f",vResult.dblVal);  
                                }  
                                else   if(vResult.vt==VT_DATE)         //时间格式  
                                {  
                                        //SYSTEMTIME   st;  
                                        //VariantTimeToSystemTime(&vResult.date,   &st);  
                                }  
                                else   if(vResult.vt==VT_EMPTY)       //单元格空的  
                                {  
                                        strSour="";  
                                }      

                                if (str.Compare(strSour) != 0)
                                {
                                        char  buffer[200];
                                        sprintf(buffer,(const char*)"源文件与目的文件在表: %s 中的列项:%s不同",sheet.GetName(),str);
                                        AfxMessageBox(buffer);
                                        return;
                                }               
                        }

                        //对每一个位置进行拷贝
                        for (long i = 2; i <= iRowNumSour; i++)
                        {
                                for (long j = 1; j <= iColNumSour; j++)
                                {

                                        iCellSour.AttachDispatch((rangeSour.GetItem(COleVariant(long(i)),   COleVariant(long(j)))).pdispVal);  
                                        vResult = iCellSour.GetText();

                                        CString   strSour;  
                                        if(vResult.vt   ==   VT_BSTR)               //字符串  
                                        {  
                                                strSour=vResult.bstrVal;  
                                        }  
                                        else   if   (vResult.vt==VT_R8)           //8字节的数字    
                                        {  
                                                strSour.Format("%f",vResult.dblVal);  
                                        }  
                                        else   if(vResult.vt==VT_DATE)         //时间格式  
                                        {  
                                                //SYSTEMTIME   st;  
                                                //VariantTimeToSystemTime(&vResult.date,   &st);  
                                        }  
                                        else   if(vResult.vt==VT_EMPTY)       //单元格空的  
                                        {  
                                                strSour="";  
                                        }      
                                        //insert into destination excel
                                        range.SetItem(COleVariant((long)(iRowNum + i - 1)),COleVariant((long)(j)),COleVariant(strSour));

                                }
                        }
                        //设置进度条的位置大小
                        pThisObj->m_pro += static_cast<int>((double)(100/(items * count)));
                       
                        //处理下一Sheet
                        lpDispSour = sheetSour.GetNext();
                        lpDisp = sheet.GetNext();
                } while(lpDispSour != NULL && lpDisp != NULL);

                book.Save();

                book.Close(covOptional,COleVariant(pThisObj->m_strDest),covOptional);

                lpDisp   =   books.Open(pThisObj->m_strDest,              
                        covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
                        covOptional,   covOptional,   covOptional,   covOptional,   covOptional,  
                        covOptional,   covOptional   );  

                //*****  
                //得到Workbook  
                book.AttachDispatch(lpDisp);  
                //books.
                //*****  
                //得到Worksheets    
                sheets.AttachDispatch(book.GetWorksheets());    

                //*****  
                //得到当前活跃sheet  
                //如果有单元格正处于编辑状态中,此操作不能返回,会一直等待  
                lpDisp=book.GetActiveSheet();  

        }

        book.Save();

        //sour
        rangeSour.DetachDispatch();
        rangeSour.ReleaseDispatch();

        sheetSour.DetachDispatch();
        sheetSour.ReleaseDispatch();

        sheetsSour.DetachDispatch();
        sheetsSour.ReleaseDispatch();

        bookSour.DetachDispatch();
        bookSour.ReleaseDispatch();

        //dest
        range.DetachDispatch();
        range.ReleaseDispatch();

        sheet.DetachDispatch();
        sheet.ReleaseDispatch();

        sheets.DetachDispatch();
        sheets.ReleaseDispatch();
        book.Close(covOptional,COleVariant(pThisObj->m_strDest),covOptional);
        book.DetachDispatch();
        book.ReleaseDispatch();
        //*****  
        //关闭所有的book,退出Excel    
        //book.
        books.Close();         
        books.DetachDispatch();
        books.ReleaseDispatch();
        delete books;
        books = NULL;

        app.Quit();                 
        app.DetachDispatch();
        app.ReleaseDispatch();      
        delete app;
        app = NULL;
       
        pThisObj->m_progress.SetPos(100);
        pThisObj->m_progress.SetText("合并完成");
        Sleep(500);//为了使用户看到已合并完成的界面
        pThisObj->EndPro();     //调用CDialog::OnOK();关闭对话框。  
}

/*===========================================================================
函 数 名:        ~CProgressDlg
功能描述:        析构函数
输入参数:        None
输出参数:        None
返回值  :        Void
创建日期:        2008-1-5
修改日期:       
作    者:        zcd

附加说明:       
-----------------------------------------------------------------------       
历史:               
修改时间                                修改人                                修改内容                                                                                                       
2008-1-5                                zcd                                创建该函数       

========================================================================*/
CProgressDlg::~CProgressDlg()
{
        //释放线程句柄
        if (m_hFileCvtThreadHandle)
        {
                CloseHandle(m_hFileCvtThreadHandle);
                m_hFileCvtThreadHandle = NULL;
        }
        //释放COM控件
        ::CoUninitialize();
        AfxMessageBox("数据合并完毕!",MB_ICONINFORMATION);

PS:非常BS公司不让上外网的做法,如果公司内网有很多资料我也不反对,问题是没有。想查什么资料只能等下班后再查,唉。。。已经习惯了晚上10点以后到家的日子。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值