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

4 篇文章 0 订阅

在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] = '\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);
		}
	}
}

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

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

 

  • 22
    点赞
  • 185
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: 在Python中,可以使用pandas库对Excel表格进行读取和写入。其中,pandas.read_excel()函数可以用来读取Excel表格,pandas.DataFrame.to_excel()函数则可以用来将DataFrame数据类型写入Excel表格读取Excel表格的示例代码如下: import pandas as pd df = pd.read_excel('example.xlsx', sheet_name='Sheet1') 其中,'example.xlsx'表示Excel表格的文件路径,'Sheet1'为要读取表格的名称。 写入Excel表格的示例代码如下: import pandas as pd data = {'Name': ['Tom', 'Sam', 'Kevin'], 'Age': [25, 30, 27], 'Gender': ['Male', 'Male', 'Female']} df = pd.DataFrame(data) df.to_excel('example.xlsx', sheet_name='Sheet1', index=False) 其中,data是一个字典类型,包含了要写入Excel表格数据。df是一个DataFrame类型,用来保存data的数据。'example.xlsx'表示要写入的Excel表格的文件路径,'Sheet1'为要写入的表格的名称。index=False表示不将行索引写入Excel表格中。 综上所述,要读取和写入Excel表格,只需要使用pandas库中的相关函数即可。 ### 回答2: Excel表格是一种常见的电子表格,它可以记录和处理各种数据,具有直观、简单、易用等特点。在Python中,可以使用第三方库openpyxl来读取和写入Excel表格。下面分别介绍如何读取和写入Excel表格的方法。 一、读取Excel表格 1. 安装openpyxl库:在命令行中输入 pip install openpyxl,即可安装openpyxl库。 2. 打开Excel表格:要使用openpyxl库读取Excel表格,首先要打开表格文件,可以使用load_workbook()方法打开文件,并返回一个workbook对象。 例如:workbook = openpyxl.load_workbook('example.xlsx') 3. 获取表格中的单元格:要获取Excel表格中的单元格,可以先选定一个工作表,然后通过其名称或坐标来获取单元格对象。 例如:worksheet = workbook['Sheet1'] cell = worksheet['A1'] 或 cell = worksheet.cell(row=1, column=1) 4. 读取单元格的值:可以使用value属性来读取单元格中的值。 例如:print(cell.value) 二、写入Excel表格 1. 创建Excel表格:要使用openpyxl库写入Excel表格,首先要创建一个workbook对象,并添加需要的工作表。 例如:workbook = openpyxl.Workbook() worksheet = workbook.active worksheet.title = 'Sheet1' 2. 写入单元格的值:也可以使用value属性来写入单元格中的值。 例如:worksheet['A1'].value = 'Python' 3. 保存Excel表格:可以使用save()方法来保存Excel表格。 例如:workbook.save('example.xlsx') 综上所述,Python通过openpyxl库可以方便地读取和写入Excel表格,这对于数据处理和分析非常有帮助。但需要注意的是,openpyxl库在读写大型Excel文件时可能会存在性能问题,因此需要合理使用并注意优化。 ### 回答3: Excel表格是一种广泛使用的电子表格,它被广泛用于记录和管理数据。Python语言中有很多可用读取和写入Excel表格的库,这里我们将重点介绍openpyxl库。 openpyxl是Python中一个用于读取和写入Excel表格的库。它可以完全处理xlsx和xlsm文件,并且提供了对Excel中电子表格、单元格、行和列的完整访问。下面我们详细介绍openpyxl库的读写操作。 读取Excel表格: 1. 导入openpyxl库 ``` import openpyxl ``` 2. 打开Excel表格 ``` workbook = openpyxl.load_workbook('file_path') ``` 3. 获取要操作的表格(可以是默认的第一个sheet页,也可以是指定的sheet页) ``` sheet = workbook['sheet_name'] # 或者 sheet = workbook.active ``` 4. 获取单元格的值 ``` cell_value = sheet['A1'].value ``` 5. 获取行和列的值 ``` row_values = [] for row in range(1, sheet.max_row+1): row_data = [] for column in range(1, sheet.max_column+1): row_data.append(sheet.cell(row=row, column=column).value) row_values.append(row_data) col_values = [] for column in range(1, sheet.max_column+1): col_data = [] for row in range(1, sheet.max_row+1): col_data.append(sheet.cell(row=row, column=column).value) col_values.append(col_data) ``` 写入Excel表格: 1. 导入openpyxl库 ``` import openpyxl ``` 2. 创建Excel表格 ``` workbook = openpyxl.Workbook() ``` 3. 创建并选择要操作的sheet页 ``` sheet = workbook.create_sheet('sheet_name', 0) ``` 4. 写入单元格的值 ``` sheet['A1'] = 'value' ``` 5. 写入行和列的值 ``` row_values = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for row in row_values: sheet.append(row) col_values = [[1, 4, 7], [2, 5, 8], [3, 6, 9]] for col in col_values: sheet.append(col) ``` 6. 保存Excel表格 ``` workbook.save('file_path') ``` 总的来说,使用openpyxl库读取和写入Excel表格非常容易,只需几行代码就可以完成读写操作。对于需要处理Excel表格的项目,openpyxl是一个非常方便和强大的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值