C++读取excel表格

windows c/c++ 专栏收录该内容
272 篇文章 4 订阅

1 创建mfc程序(这里以vs2013为例)

      到这里直接点击完成即可。

2 添加读取excel文件用到的类

  2.1 打开类向导

    

   

2.2 添加类

将_Application、_Workbook、_Worksheet、Workbooks、Worksheets添加到“生成的类”中

3 添加完成后,找到相关头文件,注释/删除

     

 #import "D:\\software\\office2010\\Office14\\EXCEL.EXE"no_namespace

4 再次编译还是有错误

     定位错误信息,将DialogBox()改为_DialogBox()

5 添加源码(最重要的一步)

5.1.Excel.h

//Excel.h
#pragma once
#include "CApplication.h"
#include "CRange.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
 
class Excel
{
private:
    CString openFileName;
    CWorkbook workBook;//当前处理文件
    CWorkbooks books;//ExcelBook集合,多文件时使用
    CWorksheet workSheet;//当前使用sheet
    CWorksheets sheets;//Excel的sheet集合
    CRange currentRange;//当前操作区域
 
    bool isLoad;//是否已经加载了某个sheet数据
 
    COleSafeArray safeArray;
 
protected:
    static CApplication application;//Excel进程实例
 
public:
    Excel();
    virtual ~Excel();
 
 
 
    void show(bool bShow);
    
    //检查一个cell是否为字符串
    bool isCellString(long iRow, long iColumn);
 
    //检查一个cell是否为数值
    bool isCellInt(long iRow, long iColumn);
 
    //得到一个cell的string
    CString getCellString(long iRow, long iColumn);
 
    //得到一个cell的整数
    int getCellInt(long iRow, long iColumn);
 
    //得到一个cell的double数据
    double getCellDouble(long iRow, long iColumn);
 
    //取得行的总数
    int getRowCount();
 
    //取得列的整数
    int getColumnCount();
 
    //使用某个shell
    bool loadSheet(long tableId, bool preLoaded = false);
    bool loadSheet(CString sheet, bool preLoaded = false);
 
 
    //通过序号取得某个shell的名称
    CString getSheetName(long tableID);
 
    //得到sheel的总数
    int getSheetCount();
 
 
 
 
    //打开excel文件
    bool open(const char* fileName);
 
    //关闭打开的excel文件
    void close(bool ifSave = false);
 
    //另存为一个excel文件
    void saveAsXLSFile(const CString &xlsFile);
 
    //取得打开文件的名称
    CString getOpenFileName();
 
    //取得打开sheel的名称
    CString getOpenSheelName();
 
    //向cell中写入一个int值
    void setCellInt(long iRow, long iColumn,int newInt);
 
    //向cell中写入一个字符串
    void setCellString(long iRow, long iColumn, CString newString);
 
 
public:
    //初始化 Excel_OLE
    static bool initExcel();
 
    //释放Excel_OLE
    static void release();
 
    //取得列的名称
    static char* getColumnName(long iColumn);
 
protected:
    void preLoadSheet();
 
 
 
};

5.2.Excel.cpp

//Excel.cpp
#include "stdafx.h"
#include <tchar.h>
#include "Excel.h"
 
 
COleVariant
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
 
CApplication Excel::application;
 
Excel::Excel() :isLoad(false)
{
}
 
 
Excel::~Excel()
{
    //close();
}
 
 
bool Excel::initExcel()
{
    //创建Excel 2000服务器(启动Excel)   
    AfxOleInit();   //先初始化ole
    if (!application.CreateDispatch(_T("Excel.application"),nullptr))
    {
        MessageBox(nullptr,_T("创建Excel服务失败,你可能没有安装EXCEL,请检查!"),_T("错误"),MB_OK);
        return FALSE;
    }
 
    application.put_DisplayAlerts(FALSE);
    return true;
}
 
 
void Excel::release()
{
    application.Quit();
    application.ReleaseDispatch();
    application = nullptr;
}
 
bool Excel::open(const char*  fileName)
{
    
    //先关闭文件
    close();
 
    //利用模板建立新文档
    books.AttachDispatch(application.get_Workbooks(), true);
 
 
    LPDISPATCH lpDis = nullptr;
    lpDis = books.Add(COleVariant(CString(fileName)));
 
    if (lpDis)
    {
        workBook.AttachDispatch(lpDis);
 
        sheets.AttachDispatch(workBook.get_Worksheets());
 
        openFileName = fileName;
        return true;
    }
 
    return false;
}
 
void Excel::close(bool ifSave)
{
    //如果文件已经打开,关闭文件
    if (!openFileName.IsEmpty())
    {
        //如果保存,交给用户控制,让用户自己存,如果自己SAVE,会出现莫名的等待  
        if (ifSave)
        {
            //show(true);
        }
        else
        {
            workBook.Close(COleVariant(short(FALSE)), COleVariant(openFileName), covOptional);
            books.Close();
        }
 
        //清空打开文件名称
        openFileName.Empty();
    }
 
 
    sheets.ReleaseDispatch();
    workSheet.ReleaseDispatch();
    currentRange.ReleaseDispatch();
    workBook.ReleaseDispatch();
    books.ReleaseDispatch();
}
 
void Excel::saveAsXLSFile(const CString &xlsFile)
{
    workBook.SaveAs(COleVariant(xlsFile),
        covOptional,
        covOptional,
        covOptional,
        covOptional,
        covOptional,
        0,
        covOptional,
        covOptional,
        covOptional,
        covOptional,
        covOptional);
    return;
}
 
 
int Excel::getSheetCount()
{
    return sheets.get_Count();
}
 
CString Excel::getSheetName(long tableID)
{
    CWorksheet sheet;
    sheet.AttachDispatch(sheets.get_Item(COleVariant((long)tableID)));
    CString name = sheet.get_Name();
    sheet.ReleaseDispatch();
    return name;
}
 
 
void Excel::preLoadSheet()
{
    CRange used_range;
 
    used_range = workSheet.get_UsedRange();
 
 
    VARIANT ret_ary = used_range.get_Value2();
    if (!(ret_ary.vt & VT_ARRAY))
    {
        return;
    }
    //  
    safeArray.Clear();
    safeArray.Attach(ret_ary);
}
 
//按照名称加载sheet表格,也可提前加载所有表格
bool Excel::loadSheet(long tableId, bool preLoaded)
{
    LPDISPATCH lpDis = nullptr;
    currentRange.ReleaseDispatch();
    currentRange.ReleaseDispatch();
    lpDis = sheets.get_Item(COleVariant((long)tableId));
    if (lpDis)
    {
        workSheet.AttachDispatch(lpDis, true);
        currentRange.AttachDispatch(workSheet.get_Cells(), true);
    }
    else
    {
        return false;
    }
 
    isLoad = false;
    //如果进行预先加载  
    if (preLoaded)
    {
        preLoadSheet();
        isLoad = true;
    }
 
    return true;
}
 
 
bool Excel::loadSheet(CString sheet, bool preLoaded)
{
    LPDISPATCH lpDis = nullptr;
    currentRange.ReleaseDispatch();
    currentRange.ReleaseDispatch();
 
    lpDis = sheets.get_Item(COleVariant(sheet));
    if (lpDis)
    {
        workSheet.AttachDispatch(lpDis, true);
        currentRange.AttachDispatch(workSheet.get_Cells(), true);
    }
    else
    {
        return false;
    }
 
    isLoad = false;
    //如果进行预先加载  
    if (preLoaded)
    {
        preLoadSheet();
        isLoad = true;
    }
 
    return true;
}
 
 
int Excel::getColumnCount()
{
    CRange range;
    CRange usedRange;
 
    usedRange.AttachDispatch(workSheet.get_UsedRange(), true);
    range.AttachDispatch(usedRange.get_Columns(), true);
    int count = range.get_Count();
 
    usedRange.ReleaseDispatch();
    range.ReleaseDispatch();
 
    return count;
}
 
int Excel::getRowCount()
{
    CRange range;
    CRange usedRange;
 
    usedRange.AttachDispatch(workSheet.get_UsedRange(), true);
    range.AttachDispatch(usedRange.get_Rows(), true);
 
    int count = range.get_Count();
 
    usedRange.ReleaseDispatch();
    range.ReleaseDispatch();
 
    return count;
}
 
bool Excel::isCellString(long iRow, long iColumn)
{
    CRange range;
    range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
    COleVariant vResult = range.get_Value2();
    //VT_BSTR标示字符串  
    if (vResult.vt == VT_BSTR)
    {
        return true;
    }
    return false;
}
 
 
bool Excel::isCellInt(long iRow, long iColumn)
{
 
    CRange range;
    range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
    COleVariant vResult = range.get_Value2();
    //VT_BSTR标示字符串  
    if (vResult.vt == VT_INT || vResult.vt == VT_R8)
    {
        return true;
    }
    return false;
}
 
CString Excel::getCellString(long iRow, long iColumn)
{
    COleVariant vResult;
    CString str;
    //字符串  
    if (isLoad == false)
    {
        CRange range;
        range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
        vResult = range.get_Value2();
        range.ReleaseDispatch();
    }
    //如果数据依据预先加载了  
    else
    {
        long read_address[2];
        VARIANT val;
        read_address[0] = iRow;
        read_address[1] = iColumn;
        safeArray.GetElement(read_address, &val);
        vResult = val;
    }
 
    if (vResult.vt == VT_BSTR)
    {
        str = vResult.bstrVal;
    }
    //整数  
    else if (vResult.vt == VT_INT)
    {
        str.Format(_T("%d"), vResult.pintVal);
    }
    //8字节的数字   
    else if (vResult.vt == VT_R8)
    {
        str.Format(_T("%0.0f"), vResult.dblVal);
    }
    //时间格式  
    else if (vResult.vt == VT_DATE)
    {
        SYSTEMTIME st;
        VariantTimeToSystemTime(vResult.date, &st);
        CTime tm(st);
        str = tm.Format(_T("%Y-%m-%d"));
 
    }
    //单元格空的  
    else if (vResult.vt == VT_EMPTY)
    {
        str = "";
    }
 
    return str;
}
 
double Excel::getCellDouble(long iRow, long iColumn)
{
    double rtn_value = 0;
    COleVariant vresult;
    //字符串  
    if (isLoad == false)
    {
        CRange range;
        range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
        vresult = range.get_Value2();
        range.ReleaseDispatch();
    }
    //如果数据依据预先加载了  
    else
    {
        long read_address[2];
        VARIANT val;
        read_address[0] = iRow;
        read_address[1] = iColumn;
        safeArray.GetElement(read_address, &val);
        vresult = val;
    }
 
    if (vresult.vt == VT_R8)
    {
        rtn_value = vresult.dblVal;
    }
 
    return rtn_value;
}
 
int Excel::getCellInt(long iRow, long iColumn)
{
    int num;
    COleVariant vresult;
 
    if (isLoad == FALSE)
    {
        CRange range;
        range.AttachDispatch(currentRange.get_Item(COleVariant((long)iRow), COleVariant((long)iColumn)).pdispVal, true);
        vresult = range.get_Value2();
        range.ReleaseDispatch();
    }
    else
    {
        long read_address[2];
        VARIANT val;
        read_address[0] = iRow;
        read_address[1] = iColumn;
        safeArray.GetElement(read_address, &val);
        vresult = val;
    }
    //  
    num = static_cast<int>(vresult.dblVal);
 
    return num;
}
 
void Excel::setCellString(long iRow, long iColumn, CString newString)
{
    COleVariant new_value(newString);
    CRange start_range = workSheet.get_Range(COleVariant(_T("A1")), covOptional);
    CRange write_range = start_range.get_Offset(COleVariant((long)iRow - 1), COleVariant((long)iColumn - 1));
    write_range.put_Value2(new_value);
    start_range.ReleaseDispatch();
    write_range.ReleaseDispatch();
}
 
void Excel::setCellInt(long iRow, long iColumn, int newInt)
{
    COleVariant new_value((long)newInt);
    CRange start_range = workSheet.get_Range(COleVariant(_T("A1")), covOptional);
    CRange write_range = start_range.get_Offset(COleVariant((long)iRow - 1), COleVariant((long)iColumn - 1));
    write_range.put_Value2(new_value);
    start_range.ReleaseDispatch();
    write_range.ReleaseDispatch();
}
 
 
void Excel::show(bool bShow)
{
    application.put_Visible(bShow);
    application.put_UserControl(bShow);
}
 
CString Excel::getOpenFileName()
{
    return openFileName;
}
 
CString Excel::getOpenSheelName()
{
    return workSheet.get_Name();
}
 
char* Excel::getColumnName(long iColumn)
{
    static char column_name[64];
    size_t str_len = 0;
 
    while (iColumn > 0)
    {
        int num_data = iColumn % 26;
        iColumn /= 26;
        if (num_data == 0)
        {
            num_data = 26;
            iColumn--;
        }
        column_name[str_len] = (char)((num_data - 1) + 'A');
        str_len++;
    }
    column_name[str_len] = '\0';
    //反转  
    _strrev(column_name);
 
    return column_name;
}

6.使用示例

//使用excel类
    Excel excl;
    bool bInit = excl.initExcel();
    char path[MAX_PATH];
    GetCurrentDirectoryA(MAX_PATH, path);//获取当前工作目录
    strcat_s(path, "\\data.xlsx");//设置要打开文件的完整路径
 
 
    bool bRet = excl.open(path);//打开excel文件
 
    CString strSheetName = excl.getSheetName(1);//获取sheet名
    bool bLoad = excl.loadSheet(strSheetName);//装载sheet
    int nRow = excl.getRowCount();//获取sheet中行数
    int nCol = excl.getColumnCount();//获取sheet中列数
 
 
    CString cell;
    for (int i = 1; i <= nRow; ++i)
    {
        for (int j = 1; j <= nCol; ++j)
        {
            cell = excl.getCellString(i, j);
        }
    }



补充:

  在原文中作者初始化excel服务时,在比如xp机器上会出现创建excel服务失败的情况,作为补充,我在初始化excel服务时添加了ole的初始化方法,

AfxOleInit();



原文链接:https://blog.csdn.net/u013507368/article/details/42143913

  • 2
    点赞
  • 0
    评论
  • 28
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值