【MFC】修改过的Excel处理类

1. 导入MFC Lib库中的 CApplication、CRange、CWorkBook、CWorkBooks、CWorkSheet、CWorkSheets

2. 将以上所有的h文件中的 #import 行 注释 并添加#include <afxdisp.h>

   例如: //#import "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace

// CApplication 包装类
#pragma once
#include <afxdisp.h>

3.处理类 .h 文件

#pragma once

#include "CApplication.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "CRange.h"
#include <map>
#include "../Control/InputInfo.h"
using namespace std;

class HandleExcelFile
{
public:
    HandleExcelFile(void);
    ~HandleExcelFile(void);
protected:
    ///打开的EXCEL文件名称
    CString  m_strFilePath;

    //EXCEL BOOK集合,(多个文件时)
    CWorkbooks   m_books; 
    //当前使用的BOOK,当前处理的文件
    CWorkbook    m_wordBook; 
    //EXCEL的sheets集合
    CWorksheets   m_sheets; 
    //当前使用sheet
    CWorksheet    m_workSheet; 
    //当前的操作区域
    CRange        m_range; 
    //进程实例
    CApplication m_app;
public:
    //初始化EXCEL OLE
    BOOL InitExcel();
    //打开Excel文件,故障判断标准
    BOOL OpenExcelFile(const CString & strFilePath, MAP_FAILURE_CRITERIA &mapFailureCriteria);
     //打开Excel文件,存量信息
    BOOL OpenExcelFile(const CString & strFilePath, MAP_INVENTORY_INFO  &mapInventoryInfo);
    //通过名称使用某个sheet
    BOOL LoadSheetAndRange(CString strSheet);
    //得到一个CELL的String
    CString GetCellString(long iRow, long iColumn);
    //得到一个CELL的int
    int GetCellInt(long irow, long icolumn);
    //得到一个CELL的Time
    CString GetCellTime(long irow, long icolumn);
    // 关闭Excel文件,释放资源
    void CloseExcelFile();
    //得到列的总数
    int GetColumnCount();
    //得到行的总数
    int GetRowCount();
    //导出ClistCtrl中的数据
    bool ExportDataFromListCtrl(CListCtrl &listCtrl);
};

4.处理类 .cpp 文件

#include "StdAfx.h"
#include "HandleExcelFile.h"
#include "../LogBulkSearchTool.h"
COleVariant
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  


HandleExcelFile::HandleExcelFile(void)
{
    m_strFilePath = "";
}

HandleExcelFile::~HandleExcelFile(void)
{
    CloseExcelFile();
}

BOOL HandleExcelFile::InitExcel()
{
    if(CoInitialize(NULL)==S_FALSE) 
    { 
        AfxMessageBox("初始化COM支持库失败!"); 
        return FALSE; 
    }
    //创建Excel 2000服务器(启动Excel) 
    if (!m_app.CreateDispatch("Excel.Application", NULL)) 
    { 
        AfxMessageBox("创建Excel服务失败!");
        return FALSE;
    }
    //m_app.put_DisplayAlerts(FALSE); 
    return TRUE;
}

//关闭打开的Excel 文件,默认情况不保存文件
void HandleExcelFile::CloseExcelFile()
{
    //如果已经打开,关闭文件
    if (!m_strFilePath.IsEmpty())
    {
        COleVariant openExcelFile(m_strFilePath);
        m_wordBook.Close(COleVariant(short(FALSE)),openExcelFile,covOptional);
        m_books.Close();

        //打开文件的名称清空
        m_strFilePath.Empty();
    }
    m_app.Quit();
    //m_app=NULL;

    m_range.ReleaseDispatch();
    m_sheets.ReleaseDispatch();
    m_workSheet.ReleaseDispatch();     
    m_wordBook.ReleaseDispatch();
    m_books.ReleaseDispatch();
    m_app.ReleaseDispatch();
    CoUninitialize();
}
///打开判断标准文件
BOOL HandleExcelFile::OpenExcelFile(const CString & strFilePath, MAP_FAILURE_CRITERIA  &mapFailureCriteria)
{ 
    if (strFilePath.IsEmpty())
    {
        AfxMessageBox("判断文件路径为空!");
        return FALSE;
    }
    CFileStatus fs;  
    if (!CFile::GetStatus(strFilePath, fs))
    {
        AfxMessageBox("判断文件路径不存在!");
        return FALSE; 
    }
    /*得到工作簿容器*/
    m_books = m_app.get_Workbooks();

    LPDISPATCH   lpDisp=NULL;
    try
    {
        lpDisp = m_books.Open(strFilePath, 
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, 
            vtMissing, vtMissing, vtMissing, vtMissing);  

    }
    catch(CException*)
    {
        AfxMessageBox("无法打开判断文件!");
        return FALSE;
    }

    if (lpDisp)
    {
        m_wordBook.AttachDispatch(lpDisp);
        m_sheets = m_wordBook.get_Worksheets();
        CString sheetName = "GULS";
        if (FALSE == LoadSheetAndRange(sheetName))
        {
             AfxMessageBox("无法打开判断文件 :sheet不存在");
             return FALSE;
        }
        

        //获取数据存储在内存
        //FailureCriteriaClass failureCriteriaClass;
        //int colTotalCount = GetColumnCount();
        int rowTotalCount = GetRowCount();
        //忽略列头开始
        for (int i = 2; i <= rowTotalCount; ++i)
        {
            FailureCriteriaClass *tempStruct = new FailureCriteriaClass();
            //ASSERT(260 == sizeof(FailureCriteriaClass) || 112 == sizeof(FailureCriteriaClass));


            tempStruct->ID = GetCellInt(i, 1);
            tempStruct->boardType = GetCellString(i,2);
            tempStruct->name = GetCellString(i, 3);
            tempStruct->reason= GetCellString(i, 4);
            tempStruct->affect= GetCellString(i, 5);

            tempStruct->level= (VOS_UINT8)GetCellInt(i, 6);
            tempStruct->rule= GetCellString(i, 7);
            tempStruct->relatedID= GetCellInt(i, 8);
            tempStruct->notes= GetCellString(i, 9);
            tempStruct->suggestion = GetCellString(i, 10);
            tempStruct->terraceNotes = GetCellString(i, 11);
            if (tempStruct->ID == 0)
            {
                delete tempStruct;
                continue;
            }

            mapFailureCriteria.insert(make_pair(tempStruct->ID, tempStruct));
        }
    }

    //记录打开的文件名称
    m_strFilePath = strFilePath;

    //m_books.Close();
    return TRUE;
}

///打开信息文件
BOOL HandleExcelFile::OpenExcelFile(const CString & strFilePath, MAP_INVENTORY_INFO  &mapInventoryInfo)
{ 
    if (strFilePath.IsEmpty())
    {
        AfxMessageBox("信息文件路径为空!");
        return FALSE;
    }
    CFileStatus fs;  
    if (!CFile::GetStatus(strFilePath, fs))
    {
        AfxMessageBox("信息文件路径不存在!");
        return FALSE; 
    }
    /*得到工作簿容器*/
    m_books = m_app.get_Workbooks();

    LPDISPATCH   lpDisp=NULL;
    try
    {
        lpDisp = m_books.Open(strFilePath, 
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, 
            vtMissing, vtMissing, vtMissing, vtMissing);  

    }
    catch(CException*)
    {
        AfxMessageBox("无法打开信息文件!");
        return FALSE;
    }

    if (lpDisp)
    {
        m_wordBook.AttachDispatch(lpDisp);
        m_sheets = m_wordBook.get_Worksheets();

        int posFileName = strFilePath.ReverseFind('\\');
        int posFileNameEnd = strFilePath.Find('.', posFileName + 1);
        CString sheetName = strFilePath.Mid(posFileName + 1, posFileNameEnd - posFileName - 1);

        if (FALSE == LoadSheetAndRange(sheetName))
        {
            AfxMessageBox("无法打开信息文件 :sheet不存在");
            return FALSE;
        }

        //获取数据存储在内存
        //int colTotalCount = GetColumnCount();
        int rowTotalCount = GetRowCount();
        //忽略列名行
        for (int i = 2; i < rowTotalCount; ++i)
        {
            InventoryInfoClass *tempStruct = new InventoryInfoClass();
            //ASSERT(260 == sizeof(InventoryInfoClass) || 112 == sizeof(InventoryInfoClass));

            tempStruct->NEName = GetCellString(i, 3);
            tempStruct->BoardName = GetCellString(i, 6);
            tempStruct->ManufactureDate = GetCellTime(i, 9);
            tempStruct->FrameNo = GetCellString(i, 10);
            tempStruct->BOMCode = GetCellString(i, 14);
            tempStruct->RackNo= GetCellString(i, 20);
            tempStruct->SerialNumber= GetCellString(i, 21); 
            tempStruct->SlotNo= GetCellString(i, 22);

            if (tempStruct->NEName == "" || tempStruct->FrameNo == "" || tempStruct->RackNo == "" || tempStruct->SlotNo == "")
            {
                delete tempStruct;
                continue;
            }
            CString key = tempStruct->NEName + '_'  + tempStruct->RackNo + '_'+ tempStruct->FrameNo + '_' + tempStruct->SlotNo;

            {//just for test
                MAP_INVENTORY_INFO::iterator itInfo = mapInventoryInfo.find(key);
                if (itInfo != mapInventoryInfo.end())
                {
                    delete tempStruct;
                    continue;
                    //ASSERT(0);
                }
            }
            mapInventoryInfo.insert(make_pair(key, tempStruct));
        }
    }

    //记录打开的文件名称
    m_strFilePath = strFilePath;
    return TRUE;
}

BOOL HandleExcelFile::LoadSheetAndRange(CString strSheet)
{
    m_range.ReleaseDispatch();
    m_workSheet.ReleaseDispatch();

    LPDISPATCH  lpDisp=NULL;
    lpDisp = m_sheets.get_Item(COleVariant(strSheet));
    if (lpDisp)
    {
        m_workSheet.AttachDispatch(lpDisp, TRUE);
        lpDisp = m_workSheet.get_Cells();
        m_range.AttachDispatch(lpDisp,TRUE);
        return TRUE;
    }
    return FALSE;
}

CString HandleExcelFile::GetCellString(long Row,long Col)
{
    CString strValue="";
    long lRow=0,lCol=0;
    lRow=GetRowCount();
    lCol=GetColumnCount();
    if(Row>lRow ||Col>lCol)
    {
        return strValue;
    }
    VARIANT lpDisp = m_range.get_Item(_variant_t(Row), _variant_t(Col));
    CRange rgRgeValue;
    rgRgeValue.AttachDispatch(lpDisp.pdispVal, TRUE);
    _variant_t vtVal = rgRgeValue.get_Value2();
    if (vtVal.vt == VT_EMPTY)
    {
        rgRgeValue.ReleaseDispatch();
        strValue = _T("");
        rgRgeValue.ReleaseDispatch();
        return strValue;
    }
    vtVal.ChangeType(VT_BSTR);
    strValue= vtVal.bstrVal;
    rgRgeValue.ReleaseDispatch();
    return strValue;
}

int HandleExcelFile::GetCellInt(long irow, long icolumn)
{
    int num = 0;
    COleVariant vresult;
    CRange range;
    range.AttachDispatch(m_range.get_Item(COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);
    vresult = range.get_Value2();
    range.ReleaseDispatch();
    num = static_cast<int>(vresult.dblVal);

    return num;
}

CString HandleExcelFile::GetCellTime(long irow, long icolumn)
{
    CString str = "";
    COleVariant vResult;
    CRange range;
    range.AttachDispatch(m_range.get_Item(COleVariant((long)irow),COleVariant((long)icolumn)).pdispVal, true);
    vResult = range.get_Value2();
    range.ReleaseDispatch();
    if(VT_R8 == vResult.vt)      
    {  
        SYSTEMTIME st;  
        VariantTimeToSystemTime(vResult.date, &st);  
        CTime tm(st);   
        str=tm.Format("%Y-%m-%d");
    }
    return str;
}

//得到列的总数
int HandleExcelFile::GetColumnCount()
{
    CRange range;
    CRange usedRange;
    usedRange.AttachDispatch(m_workSheet.get_UsedRange(), true);
    range.AttachDispatch(usedRange.get_Columns(), true);
    int count = range.get_Count();
    usedRange.ReleaseDispatch();
    range.ReleaseDispatch();
    return count;
}

//得到行的总数
int HandleExcelFile::GetRowCount()
{
    CRange range;
    CRange usedRange;
    usedRange.AttachDispatch(m_workSheet.get_UsedRange(), true);
    range.AttachDispatch(usedRange.get_Rows(), true);
    int count = range.get_Count();
    usedRange.ReleaseDispatch();
    range.ReleaseDispatch();
    return count;
}
static void   GetCellName(int nRow, int nCol, CString &strName)
{
    CString strRow;
    char cCell = (char)('A' + nCol - 1);

    strName.Format(_T("%c"), cCell);
    strRow.Format(_T( "%d "), nRow);
    strName += strRow;
}
bool HandleExcelFile::ExportDataFromListCtrl(CListCtrl &listCtrl)
{
    // 默认保存文件名
    CTime tm = CTime::GetCurrentTime();
    CString time = tm.Format("%Y%m%d");
    CString outPutName;
    outPutName.Format("输出结果_%s", time);

     CFileDialog FileDialog(FALSE,"xlsx",outPutName,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 
         _T("Microsoft Excel 2007(*.xlsx)|*.xlsx|所有文件(*.*)"),NULL); 
    if(FileDialog.DoModal()!=IDOK) 
    {
        return false;
    }
    CString cStrFile=FileDialog.GetPathName();  //选择保存路径名称
    

    if(::PathFileExists(cStrFile)) 
    {
        DeleteFile(cStrFile); 
    }

    int   m_rows = listCtrl.GetItemCount();  //获取行数
    if (m_rows == 0)
    {
        AfxMessageBox("请分析以后进行导出操作");
        return false;
    }
    CHeaderCtrl   *pmyHeaderCtrl= listCtrl.GetHeaderCtrl(); //获取表头
    int   m_cols   = pmyHeaderCtrl-> GetItemCount(); //获取列数

    m_books = m_app.get_Workbooks();
    m_wordBook = m_books.Add(covOptional);

    m_sheets = m_wordBook.get_Worksheets();
    m_workSheet = m_sheets.get_Item(COleVariant((short)1));  //得到第一个工作表   

    TCHAR     lpBuffer[256];    

    HDITEM   hdi; 
    hdi.mask   =   HDI_TEXT;
    hdi.pszText   =   lpBuffer;
    hdi.cchTextMax   =   256; 

    CString   colname;
    CString strTemp;

    int   iRow,iCol;
    for(iCol=0;   iCol <m_cols;   iCol++)//将列表的标题头写入EXCEL 
    { 
        GetCellName(1 ,iCol + 1, colname); //(colname就是对应表格的A1,B1,C1,D1)
        m_range   =   m_workSheet.get_Range(COleVariant(colname),COleVariant(colname));  
        pmyHeaderCtrl-> GetItem(iCol,   &hdi); //获取表头每列的信息
        m_range.put_Value2(COleVariant(hdi.pszText));  //设置每列的内容
        int   nWidth   =   listCtrl.GetColumnWidth(iCol)/6; 

        //得到第iCol+1列   
        m_range.AttachDispatch(m_range.get_Item(_variant_t((long)(iCol+1)),vtMissing).pdispVal,true);   

        //设置列宽  
        m_range.put_ColumnWidth(_variant_t((long)nWidth));
    } 

    m_range   =   m_workSheet.get_Range(COleVariant( _T("A1 ")),   COleVariant(colname)); 
    m_range.put_RowHeight(_variant_t((long)30));//设置行的高度 
    m_range.put_VerticalAlignment(COleVariant((short)-4108));//xlVAlignCenter   =   -4108 

    COleSafeArray   saRet; //COleSafeArray类是用于处理任意类型和维数的数组的类
    DWORD   numElements[]={m_rows,m_cols};       //行列写入数组
    saRet.Create(VT_BSTR,   2,   numElements); //创建所需的数组

    m_range = m_workSheet.get_Range(COleVariant( _T("A2 ")),covOptional); //从A2开始
    m_range = m_range.get_Resize(COleVariant((short)m_rows),COleVariant((short)m_cols)); //表的区域

    long   index[2] = {0};  

    for(   iRow   =   1;   iRow   <=   m_rows;   iRow++)//将列表内容写入EXCEL 
    { 
        for   (   iCol   =   1;   iCol   <=   m_cols;   iCol++)  
        { 
            index[0]=iRow-1; 
            index[1]=iCol-1; 

            CString   szTemp; 
            szTemp=listCtrl.GetItemText(iRow-1,iCol-1); //取得m_list控件中的内容

            BSTR   bstr   =   szTemp.AllocSysString(); 
            saRet.PutElement(index,bstr); //把m_list控件中的内容放入saRet

            SysFreeString(bstr);
        } 
    }  
    //记录打开的文件名称
    m_strFilePath = cStrFile;

    m_range.put_Value2(COleVariant(saRet)); //将得到的数据的saRet数组值放入表格
    m_wordBook.SaveCopyAs(COleVariant(cStrFile)); //保存到cStrFile文件
    m_wordBook.put_Saved(true);
    return true;
}


你可能感兴趣的:(Excel,Class,mfc)