2025年轻松解析excel文件 —-利用MFC读取excel文件

轻松解析excel文件 —-利用MFC读取excel文件在项目中需要解析 excel 文件 尝试了很多办法 最后还是利用 MFC 自带的解析 Excel 类 网上的资源很多 前面添加类步骤基本差不多 都能成功 但是在自己写类进行封装的时候 抄袭现象很明显 很多错误还是接着一字不差的发上来 最后找了一个错误不是很多的 自己修改封装 先附上一个 demo 1 在 Button 控件下添加以下代码用于选取需要读取的文件 string path path

在项目中需要解析excel文件,尝试了很多办法,最后还是利用MFC自带的解析Excel类。网上的资源很多,前面添加类步骤基本差不多,都能成功,但是在自己写类进行封装的时候,抄袭现象很明显,很多错误还是接着一字不差的发上来。最后找了一个错误不是很多的,自己修改封装,先附上一个demo。

(1)在Button控件下添加以下代码用于选取需要读取的文件

string path;
path = CT2A(Infilepath);
//char* path = const_cast(line1.c_str()); //sting 转 char*
Excel excl;
bool bInit = excl.initExcel();

//打开excel文件
if (!excl.open(path.c_str()))
{
AfxMessageBox(_T("excel文件打开出错!"));
}

CString strSheetName = excl.getSheetName(1);//获取sheet名
bool bLoad = excl.loadSheet(strSheetName);//装载sheet
int nRow = excl.getRowCount();//获取sheet中行数
//int nCol = excl.getColumnCount();//获取sheet中列数

(2)在需要调用的地方添加以下代码,可以读取任意表格

        string path;
path = CT2A(Infilepath);
//char* path = const_cast(line1.c_str()); //sting 转 char*
Excel excl;
bool bInit = excl.initExcel();

//打开excel文件
if (!excl.open(path.c_str()))
{
AfxMessageBox(_T("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;
string cells;
for (int i = 1; i <= nRow; ++i)
{
for(int j = 1; j <= nCol ; ++j){
cell = excl.getCellString(i, j); 获取一个单元格数据
cells = CT2A(cell); //将获取的单元格转换为string类型数据
}
}

以上代码经过VS实测,保证正确。

下面附上详细调用MFC excel类的过程以及封装好的excel类。

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

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

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

2.1 打开类向导(ctrl + alt + x)

2.2 添加类

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

3 添加完成后,找到所有刚添加的相关头文件,注释/删除第一句话

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

4 再次编译还是有错误

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

5 特别注意:如果在有stdafx头文件时,一定要在每个头文件之前都加上,不然会报错(这个坑我进去很久才出来)

到此,MFC里面解析excel就添加成功了。

最后添加上封装好excel.h和excel.cpp文件。以下为源码,保证能运行

//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();
};
//Excel.cpp

#include "stdafx.h"
#include
#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)
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(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;
}

到这儿就能正常解析excel文件

ps:demo里面仅仅展示了excel类的部分功能,按照需要使用…….

编程小号
上一篇 2025-02-23 19:06
下一篇 2025-04-02 23:06

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/146893.html