MFC读取 Excel

news2024/9/22 1:07:03

2.添加读取excel数据的接口类:

 

 

添加读取excel的接口类: 

 

 3、添加完成后,找到这几个接口类的头文件,注释/删除 下图红框中的引入语句

注意:每个接口类的头文件都需进行处理。

 

4、添加源文件

excel.h文件:

#pragma once
#include "CApplication.h"
#include "CRange.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "stdafx.h"
 
class Excel
{
public:
	Excel();
	~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);
 
	//通过序号取得某个sheet的名称
	CString getSheetName(long tableID);
 
	//得到sheet的总数
	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();
 
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进程实例
};

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)   
	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;
}

5、在对话框中添加按钮和静态文本框:

为静态文本框IDC_STATIC1控件添加控件变量

 在readexcelDlg.h中添加对excel类的引用,

在readexcelDlg.h中声明一个excel类的对象

Excel excel;
编译程序,可能会弹出如下的错误:

 在DialogBox前加下划线即:_DialogBox (具体原理不知道)

再次编译就OK了。

6、使用excel类

在button的单击事件中完成下述代码:

void CreadexcelDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	//使用excel类
	bool bInit = m_excel.initExcel();
	char path[MAX_PATH];
	GetCurrentDirectoryA(MAX_PATH, path);//获取当前工作目录
	strcat_s(path,"\\data\\001.xlsx");//设置要打开文件的完整路径
 
	bool bRet = m_excel.open(path);//打开excel文件
 
	CString strSheetName = m_excel.getSheetName(1);//获取sheet名
	m_sheetname.SetWindowTextW(strSheetName);      //显示读取excel的数据表名
 
	bool bLoad = m_excel.loadSheet(strSheetName);//装载sheet
	int nRow = m_excel.getRowCount();//获取sheet中行数
	int nCol = m_excel.getColumnCount();//获取sheet中列数
 
	CString cell;
	for (int i = 1; i <= nRow; ++i)
	{
		for (int j = 1; j <= nCol; ++j)
		{
			cell = m_excel.getCellString(i, j);
		}
	}
}

OK 了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring websocket并发发送消息异常的解决

https://www.jb51.net/program/297186nkq.htm本文主要介绍了 Spring websocket并发发送消息异常的解决,当多个线程同时尝试通过 WebSocket 会话发送消息时,会抛出异常,下面就来解决一下,感兴趣的可以了解一下https://www.jb51.net/program/297186nkq.htm

centos系统配置转发和iptables使之成为网关

centos系统配置转发和iptables使之成为网关 在当下互联网环境中&#xff0c;有很多内网服务器不能出网&#xff0c;例如安装软件包&#xff0c;更新程序之类的&#xff0c;偶尔会需要出网&#xff0c;下面这种方式就是专门解决这个事情的。 如下配置在 centos 6 7 8 rocky 8 …

FPGA 最小系统 EP2C5T144C8N

参考 &#xff1a; 微雪 ep2c5t 米尔 所需元件&#xff1a; 1.2v 3.3v稳压芯片 7个10k电阻 一个use blast 5v-》3.3v稳压-》1.2v稳压 1.JTAG连接 JTAG连接 NSTATUS nconfig config_done 因为没有外部存储器&#xff0c;直接使用Jtag烧录&#xff0c;从而nconfig 为3.3 &…

全场景——(三)USB开发基础(2)

文章目录 一、USB 描述符1.1 USB 设备状态切换图1.2 标准设备请求1.2.1 SETUP事务的数据格式1.2.2 标准设备请求1.2.3 设备/配置/接口/端点 1.3 描述符1.3.1 设备描述符1.3.2 配置描述符1.3.3 接口描述符1.3.4 端点描述符1.3.5 示例 1.4 设备枚举过程示例 二、USBX 组件2.1 Azu…

Rhinoceros 8 for Mac/Win:重塑三维建模边界的革新之作

Rhinoceros 8&#xff08;简称Rhino 8&#xff09;&#xff0c;作为一款由Robert McNeel & Assoc公司开发的顶尖三维建模软件&#xff0c;无论是对于Mac还是Windows用户而言&#xff0c;都是一款不可多得的高效工具。Rhino 8以其强大的功能、广泛的应用领域以及卓越的性能&…

阿里云发送短信功能(Java)

&#xff08;1&#xff09;注册用户&#xff0c;并且开通短信套餐 &#xff08;2&#xff09; 点击快速学习&#xff0c;然后绑定测试的手机号码。 选用专用测试签名&#xff08;自定义的话阿里可能会验证什么什么的比较麻烦&#xff09; 然后在选取调用API &#xff08;3&…

Excel ——3个实用的随机函数(RAND 、RANDBETWEEN、RANDARRAY)

1、RAND 函数 RAND 函数是一个没有参数的函数&#xff1a;RAND () 返回一个大于等于 0&#xff0c;小于 1 的随机实数。 选中任一单元格&#xff0c;在编辑栏输入公式&#xff1a; 如果要生成 a 与 b 之间的随机数&#xff0c;就用&#xff1a; RAND()*(b-a)a 比如要生成-5…

Docker Compose运行Elasticsearch

前提&#xff1a;确保你已经安装了Docker和Docker Compose 创建项目目录 创建一个目录来存放项目文件 mkdir es cd es 创建docker-compose.yml文件 touch docker-compose.yml version: 3.3 services: elasticsearch: image: docker.elastic.co/elasticsearch/elastics…

mysql windows、Ubuntu安装与远程连接配置

下载 在Windows下安装MySQL需要在官网下载安装包 官网地址www.mysql.com 找到社区下载 选择适用于Windows的MYSQL安装程序 选择自己电脑对应的版本和所要下载的mysql版本一般是5.7版本和8.0版本 按照图片上的选项进行安装 到此就安装完成了 需要自己手动配置环境变量…

光纤猫光功率正常值是多少

光纤猫光功率正常值是多少 1. 光猫发送的光功率正常范围为负15dBm。 2. 光猫接收的光功率理想值为负9dBm至负27dBm。 3. 光模块发射的光功率应为0dBm或正1dBm以上。 4. 光信号通过一级光交箱跳纤会损失1到2dBm&#xff0c;因此到达一级光分箱的主纤光功率为负2dBm。 5. 经过一级…

模拟实现Stack的适配器【栈】【C++】

P. S.&#xff1a;以下代码均在VS2022环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

sentinel 02 核心类

01 02. 03. 04. 05. 4.1 4.2 4.3 4.4 5调用链

JavaScript学习笔记(十二):JS Web API

1、Web API - 简介 Web API 是开发人员的梦想。 它可以扩展浏览器的功能它可以极大简化复杂的功能它可以为复杂的代码提供简单的语法 1.1 什么是 Web API&#xff1f; API 指的是应用程序编程接口&#xff08;Application Programming Interface&#xff09;。 Web API 是 …

基于SpringBoot的网上宠物店系统

系统背景 在当今快节奏的城市生活中&#xff0c;宠物逐渐成为许多家庭不可或缺的一员&#xff0c;它们不仅是忠诚的伴侣&#xff0c;更是心灵的慰藉。随着宠物市场的日益扩大&#xff0c;人们对于宠物相关服务的需求也日益增长&#xff0c;从宠物食品、玩具到健康护理、训练课程…

SAP-MM-框架协议和货源清单的配合使用

一、业务场景: 某公司一直使用源清单功能,新增框架协议功能, 根据业务需求,公司与供应商签订备货框架协议,供应商要求我司提供单号用于备货使用,但业务部门要求,此单号不能在SRM系统中体现,不能直接做送货单,需要转正式采购订单才能在SRM系统中创建送货单,用于送货…

腾讯云 AI 代码助手四大基础功能介绍

引言 随着技术的不断进步&#xff0c;软件开发者们面临着日益复杂的编程任务和挑战。他们不仅需要处理大量的代码&#xff0c;还要在保证代码质量的前提下&#xff0c;提高开发效率。在这样的背景下&#xff0c;一款能够辅助开发者进行高效编码的工具显得尤为重要。 腾讯云AI…

数字文化产业:融合科技与人文的先锋力量

在当今数字化的时代&#xff0c;数字文化产业正以惊人的速度崛起&#xff0c;成为经济发展和文化繁荣的重要驱动力。那么&#xff0c;究竟什么是数字文化产业呢&#xff1f; 数字文化产业是文化与科技深度融合的产物。它借助先进的数字技术&#xff0c;如大数据、人工智能、虚拟…

【论文分享】通过社交媒体图片和计算机视觉分析城市绿道的使用情况

城市街道为路面跑步提供了环境。本次给大家带来一篇SCI论文的全文翻译&#xff01;该论文提出了一种非参数方法&#xff0c;使用机器学习模型来预测路面跑步强度。该论文提供了关于路面跑步的实证证据&#xff0c;并突出了规划者、景观设计师和城市管理者在设计适于跑步的城市街…

【数学建模】MATLAB快速入门

文章目录 1. MATLAB界面与基本操作1.1 MATLAB的基本操作 2. MATLAB字符串和文本2.1 string变量2.2 char变量 3. MATLAB的矩阵运算 1. MATLAB界面与基本操作 初始界面&#xff1a; 刚开始的界面只要一个命令行窗口&#xff0c;为了使编辑界面出现我们需要新建一个文件&#xff…

探索 HarmonyOS 的层叠布局:灵活的 Stack 容器

在应用开发中&#xff0c;灵活的布局设计是提高用户体验的关键之一。HarmonyOS 提供了丰富的布局组件&#xff0c;其中层叠布局&#xff08;Stack Layout&#xff09;是一个强大的工具&#xff0c;可以帮助开发者轻松实现元素的重叠显示。本文将深入探讨 Stack 容器的功能和应用…