MFC操作excel实战


// COperateExcelDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "COperateExcel.h"
#include "COperateExcelDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
const int COUNT_OF_CHARACTER = 26;
class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_ABOUTBOX };
#endif

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CCOperateExcelDlg 对话框



CCOperateExcelDlg::CCOperateExcelDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_COPERATEEXCEL_DIALOG, pParent)
    , m_cstrFile(L"D:\\test.xlsx")
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCOperateExcelDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CCOperateExcelDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON_NEW, &CCOperateExcelDlg::OnBnClickedButtonNew)
    ON_BN_CLICKED(IDC_BUTTON_OPEN, &CCOperateExcelDlg::OnBnClickedButtonOpen)
    ON_BN_CLICKED(IDC_BUTTON_MODIFY, &CCOperateExcelDlg::OnBnClickedButtonModify)
    ON_BN_CLICKED(IDC_BUTTON_SAVE, &CCOperateExcelDlg::OnBnClickedButtonSave)
END_MESSAGE_MAP()


// CCOperateExcelDlg 消息处理程序

BOOL CCOperateExcelDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 将“关于...”菜单项添加到系统菜单中。

    // IDM_ABOUTBOX 必须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);         // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    // TODO: 在此添加额外的初始化代码

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CCOperateExcelDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CCOperateExcelDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);

        // 使图标在工作区矩形中居中
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCOperateExcelDlg::OnQueryDragIcon()
{
    return static_cast(m_hIcon);
}



void CCOperateExcelDlg::OnBnClickedButtonNew()
{
    // TODO: 在此添加控件通知处理程序代码
    CApplication excelApp;
    CWorkbooks excelBooks;
    CWorkbook excelBook;
    CWorksheets excelSheets;
    CWorksheet excelSheet;
    CRange excelRange;
    COleVariant covOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        OutputDebugString(L"Failed to call CoInitialize");
        return;
    }
    if (!excelApp.CreateDispatch(L"Excel.Application"))
    {
        OutputDebugString(L"Create excel application failed");
        return;
    }
    excelApp.put_UserControl(FALSE);//用户不能操作
    excelBooks.AttachDispatch(excelApp.get_Workbooks());
    excelBook = excelBooks.Add(covOptional);
    excelSheets.AttachDispatch(excelBook.get_Sheets());
    excelSheet.AttachDispatch(excelSheets.get_Item(variant_t(1)));
    excelRange.AttachDispatch(excelSheet.get_Range(COleVariant(L"A1"), COleVariant(L"A1")));
    excelRange.put_Value2(COleVariant(L"1314"));
    excelRange.put_Value2(COleVariant(L"5201314"));//Modify the value
    CString cstrData; 
    GetCellValue(excelRange, cstrData);
    OutputDebugString(cstrData);
    excelRange.ReleaseDispatch();

    //Merge A1-B2
    excelRange.AttachDispatch(excelSheet.get_Range(COleVariant(IndexToString(1, 1)), 
        COleVariant(IndexToString(2, 2))));
    excelRange.Merge(variant_t(long(0)));

    excelBook.put_Saved(true);
    if (TRUE == PathFileExists(m_cstrFile))
        excelBook.Save();//Save
    else
        excelBook.SaveCopyAs(COleVariant(m_cstrFile));//Save as
    excelApp.put_UserControl(TRUE);
    excelRange.ReleaseDispatch();
    excelSheet.ReleaseDispatch();
    excelSheets.ReleaseDispatch();
    excelBook.ReleaseDispatch();
    excelBooks.ReleaseDispatch();
    excelApp.Quit();
    excelApp.ReleaseDispatch();
    CoUninitialize();
}


void CCOperateExcelDlg::OnBnClickedButtonOpen()
{
    // TODO: 在此添加控件通知处理程序代码
    CApplication excelApp;
    CWorkbooks excelBooks;
    CWorkbook excelBook;
    CWorksheets excelSheets;
    CWorksheet excelSheet;
    CRange excelRange;
    COleVariant colOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        OutputDebugString(L"Failed to call CoInitialize");
        return;
    }
    if (!excelApp.CreateDispatch(L"Excel.Application"))
    {
        OutputDebugString(L"Create excel application failed");
        return;
    }
    LPDISPATCH lpDisp;
    excelBooks = excelApp.get_Workbooks();
    if (TRUE == PathFileExists(m_cstrFile))
    {
        lpDisp = excelBooks.Open(m_cstrFile, colOptional, colOptional, colOptional, colOptional,
            colOptional, colOptional, colOptional, colOptional, colOptional, colOptional, colOptional,
            colOptional, colOptional, colOptional);
    }
    else
    {
        CString cstrDebug;
        cstrDebug.Format(L"File:%s not exist\n", m_cstrFile);
        OutputDebugString(cstrDebug);
        return;
    }
    excelBook.AttachDispatch(lpDisp);
    excelSheets = excelBook.get_Sheets();
    excelSheet = excelSheets.get_Item(COleVariant(short(1)));//start with 1
    excelSheet.put_Name(L"data");
    excelRange = excelSheet.get_Range(COleVariant(IndexToString(1, 1)), COleVariant(IndexToString(1, 1)));
    CString cstrData;
    GetCellValue(excelRange, cstrData);
    OutputDebugString(cstrData);

    //Add sheet
    excelSheets.Add(vtMissing, variant_t(excelSheet), variant_t(short(1)), vtMissing);
    int nCnt = excelSheets.get_Count();//Get sheet count
    CWorksheet sheetTmp = excelSheets.get_Item(COleVariant(short(2)));
    sheetTmp.put_Name(L"info");
    CRange rangeTmp = sheetTmp.get_Range(COleVariant(L"A1"), COleVariant(L"A1"));
    rangeTmp.put_Value2(COleVariant(L"Hello wite"));
    rangeTmp.ReleaseDispatch();
    sheetTmp.ReleaseDispatch();

    excelBook.put_Saved(true);
    excelBook.Save();//Save
    //Release
    excelRange.ReleaseDispatch();
    excelSheet.ReleaseDispatch();
    excelSheets.ReleaseDispatch();
    excelBook.ReleaseDispatch();
    excelBooks.ReleaseDispatch();
    excelApp.Quit();
    excelApp.ReleaseDispatch();
    CoUninitialize();
}


void CCOperateExcelDlg::OnBnClickedButtonModify()
{
    // TODO: 在此添加控件通知处理程序代码
}


void CCOperateExcelDlg::OnBnClickedButtonSave()
{
    // TODO: 在此添加控件通知处理程序代码
    CString cstrFile(L"D:\\text.txt");
    /*std::fstream fout(cstrFile,std::ios::app);
    if (!fout.is_open())
    {
        OutputDebugString(L"Open file failed\n");
        return;
    }
    for (int nIndex = 1; nIndex < 10; ++nIndex)
        fout << nIndex << '\t';
    fout << std::endl;
    fout.close();*/
    CApplication excelApp;
    CWorkbooks excelBooks;
    CWorkbook excelBook;
    CWorksheets excelSheets;
    CWorksheet excelSheet;
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        OutputDebugString(L"Failed to call CoInitialize");
        return;
    }
    if (!excelApp.CreateDispatch(L"Excel.Application"))
    {
        OutputDebugString(L"Create excel application failed");
        return;
    }
    COleVariant colOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);
    CString cstrExcel(L"D:\\abc.xlsx");
    excelBooks = excelApp.get_Workbooks();
    if (TRUE == PathFileExists(cstrExcel))
    {
        LPDISPATCH lpDisp;
        lpDisp = excelBooks.Open(cstrExcel, colOptional, colOptional, colOptional, colOptional,
            colOptional, colOptional, colOptional, colOptional, colOptional, colOptional, colOptional,
            colOptional, colOptional, colOptional);
        excelBook.AttachDispatch(lpDisp);
        excelSheets = excelBook.get_Sheets();

    }
    else
    {
        excelBooks.AttachDispatch(excelApp.get_Workbooks());
        excelBook = excelBooks.Add(colOptional);
        excelSheets.AttachDispatch(excelBook.get_Sheets());
    }

    excelSheet.AttachDispatch(excelSheets.get_Item(variant_t(short(1))));
    SaveDataToExcel(cstrFile, excelBooks, excelSheet);

    excelBook.put_Saved(true);

    if (TRUE == PathFileExists(cstrExcel))
        excelBook.Save();
    else
        excelBook.SaveCopyAs(COleVariant(cstrExcel));

    excelSheet.ReleaseDispatch();
    excelSheets.ReleaseDispatch();
    excelBook.ReleaseDispatch();
    excelBooks.ReleaseDispatch();
    excelApp.Quit();
    excelApp.ReleaseDispatch();

}

//Get cell data
void CCOperateExcelDlg::GetCellValue(CRange range, CString & cstrData)
{
    COleVariant rValue = (COleVariant)range.get_Value2();
    rValue.ChangeType(VT_BSTRT);
    cstrData = rValue.bstrVal;
}

CString CCOperateExcelDlg::IndexToString(int nRow, int nCol)
{
    CString cstrRst;
    if (nCol > COUNT_OF_CHARACTER)
        cstrRst.Format(L"%c%c%d", 'A' + (nCol - 1) / COUNT_OF_CHARACTER - 1, 'A' + (nCol - 1) % COUNT_OF_CHARACTER, nRow);
    else
        cstrRst.Format(L"%c%d", 'A' + (nCol - 1) % COUNT_OF_CHARACTER, nRow);
    return cstrRst;
}

long CCOperateExcelDlg::GetRowCount(CWorksheet sheet)
{
    CRange usedRange, range;
    usedRange.AttachDispatch(sheet.get_UsedRange());
    range.AttachDispatch(usedRange.get_Rows());
    long nRow = range.get_Count();
    range.ReleaseDispatch();
    usedRange.ReleaseDispatch();
    return nRow;
}

long CCOperateExcelDlg::GetColCount(CWorksheet sheet)
{
    CRange usedRange, range;
    usedRange.AttachDispatch(sheet.get_UsedRange());
    range.AttachDispatch(usedRange.get_Columns());
    long nCol = range.get_Count();
    range.ReleaseDispatch();
    usedRange.ReleaseDispatch();
    return nCol;
}

void CCOperateExcelDlg::SaveDataToExcel(const CString & cstrFile, CWorkbooks & books, CWorksheet & sheet)
{
    if (FALSE == PathFileExists(cstrFile))
    {
        OutputDebugString(L"文件不存在\n");
        return;
    }
    variant_t temp(cstrFile);
    VARIANT tempVariant = temp;
    LPDISPATCH lpdis = 0;
    try
    {
        lpdis = books.Add(tempVariant);
    }
    catch (COleDispatchException& e)
    {
        USES_CONVERSION;
        CT2A cSource(e.m_strSource);
        std::string errorSource = cSource;

        CT2A cDesription(e.m_strDescription);
        std::string errorDes = cDesription;

        CString es;
        es.Format(_T("csv add books except [%x - %s -%s]."),
            e.m_scError, errorSource.c_str(), errorDes.c_str());
        OutputDebugString(es);
    }
    CWorkbook bookTemp;
    CWorksheets sheetsTemp;
    CWorksheet sheetTemp;
    CRange range, rangeTemp;
    bookTemp.AttachDispatch(lpdis);
    sheetsTemp.AttachDispatch(bookTemp.get_Sheets());
    sheetTemp.AttachDispatch(sheetsTemp.get_Item(variant_t(short(1))));
    long nSrcRow = GetRowCount(sheetTemp);
    long nSrcCol = GetColCount(sheetTemp);
    long nRstRow = GetRowCount(sheet);
    long nRstCol = GetColCount(sheet);
    if (1 != nRstCol)nRstCol += 1;
    rangeTemp.AttachDispatch(sheetTemp.get_Range(COleVariant(IndexToString(1, 1)), COleVariant(IndexToString(nSrcRow, nSrcCol))));
    range.AttachDispatch(sheet.get_Range(COleVariant(IndexToString(1, nRstCol)), COleVariant(IndexToString(1, nRstCol + nSrcCol - 1))));
    rangeTemp.Copy(vtMissing);
    range.PasteSpecial(12, -4142, vtMissing, vtMissing);
    rangeTemp.ReleaseDispatch();
    range.ReleaseDispatch();
    sheetTemp.ReleaseDispatch();
    sheetsTemp.ReleaseDispatch();
    bookTemp.ReleaseDispatch();
    SetDataFormat(sheet);
}

void CCOperateExcelDlg::SetDataFormat(CWorksheet & sheet)
{
    CRange range;
    range.AttachDispatch(sheet.get_Range(variant_t(L"A1"), variant_t(L"A1")));
    range.put_NumberFormatLocal(variant_t(L"0.00"));
    CBorders border;
    border.AttachDispatch(range.get_Borders());
    CBorders borderTemp;
    borderTemp.AttachDispatch(border.get_Item(variant_t((short)xlEdgeRight)));
    borderTemp.put_LineStyle(_variant_t(1));
    borderTemp.ReleaseDispatch();
    border.ReleaseDispatch();
    range.ReleaseDispatch();

}

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