• C++环境下读取excel表格,亲测可用


    在VS2015环境中,个人对以下程序和步骤进行了测试,结果表明完全可以读取excel数据。

    相关的完整程序可以在https://download.csdn.net/download/cxd3341/12683449 中获取

    以下为程序创建步骤:

    1、新建MFC程序:

    新建基于对话框的MFC程序: 

     

     

     

     单击完成,即完成基于MFC对话框的程序的创建。

    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] = '';
    	//反转  
    	_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);
    		}
    	}
    }

     下图为项目文件夹下data文件夹中的excel文件001.xlsx

     7、运行程序,结果如下图所示,成功读取excel数据表的相关信息。

     

    注:文章转自如下地址

    https://blog.csdn.net/cxd3341/article/details/107779314?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

  • 相关阅读:
    图片验证码, 登录, 注销, 修改密码
    注册页面及注册功能实现
    高级配置文件, csrf, django settings源码, django auth模块, 文件配置的插拔式设计
    cookie操作, session操作, django中间件
    半自动创建多对多关系表, forms组件
    sweetalert, bulk_create, 分页器
    orm查询优化, MVC与MTV, choices参数, ajax
    聚合查询, 分组查询, F与Q查询, 常见字段及参数, 自定义Char字段, 事务操作
    Contest2058
    ACM版《孔乙己》
  • 原文地址:https://www.cnblogs.com/roea1/p/13546560.html
Copyright © 2020-2023  润新知