C++ MFC实现list控件对Excel的读取
2023-06-13 09:12:22 时间
大家好,又见面了,我是你们的朋友全栈君。
前面已经讲过了C++ MFC程序对Excel文件的写入,链接如下:
https://blog.csdn.net/V_Gogol/article/details/81782644
后面很长时间没有更新读取数据操作,非常抱歉!看到网上有朋友问了读取的方法,于是就再写一了这一篇关于读取操作的博文。
读取和写入大体相似,要引入的头文件和相关配置也是一样的,具体可以先看上面那一篇关于写入的博文,此篇为了节省篇幅便于阅读,就只写读取的具体代码和解释。
我将读取和写入操作都封装成了一个专门的类,便于后续的调用:
list控件读取Excel数据
将Excel数据读取到mfc控件中,我写的函数适用于Excel文件列数和list控件列数相同的情况,此处提供源码,读者可根据源码改成更通用的情况。具体代码如下:
//参数为列表控件
void CFileRW::ExcelToList(CListCtrl *datalist)
{
//文件对话框,打开具体Excel文件
CFileDialog filedlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
L"excel文件(*.xls)|*.xlsx|ALL Files(*.*)||"); //TRUE为打开,FALS为保存
if (IDOK != filedlg.DoModal())
{
return;
}
//获取文件路径
readxlspath = filedlg.GetPathName();
if (!PathFileExists(readxlspath))
{
AfxMessageBox(readxlspath + "不存在");
return;
}
if (!app.CreateDispatch(L"Excel.Application")) //创建接口对象
{
AfxMessageBox(L"无法启动Excel服务器");
return;
}
COleVariant covOption((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//得到工作簿
books.AttachDispatch(app.get_Workbooks());
lpdisp = books.Open(readxlspath, covOption, covOption, covOption, covOption,
covOption, covOption, covOption, covOption, covOption, covOption,
covOption, covOption, covOption, covOption);
//得到Workbook
book.AttachDispatch(lpdisp);
//sheets
sheets.AttachDispatch(book.get_Worksheets());
得到WorkSheet
//sheet.AttachDispatch(sheets.get_sheet());
//得到当前活跃sheet
//如果有单元格正处于编辑状态,此操作不会返回,会一直等待
lpdisp = book.get_ActiveSheet();
sheet.AttachDispatch(lpdisp);
usedrange.AttachDispatch(sheet.get_UsedRange());
COleVariant vResult,vResult1;
//读取已经使用区域的信息,包括已经使用的行数、列数、起始行、起始列
range.AttachDispatch(sheet.get_UsedRange());
//取得已经使用的行数
range.AttachDispatch(range.get_Rows());
long rownum = range.get_Count();
//取得已经使用的列数
range.AttachDispatch(range.get_Columns());
long colnum = range.get_Count();
//取得已使用区域的起始行,从1开始
long startrow = range.get_Row();
//取得已使用区域的起始列,从1开始
long startcol = range.get_Column();
//清空list控件内容
datalist->DeleteAllItems();
for (int i = startrow; i <= rownum; i++)
{
//先插入行首,即首列元素
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch(range.get_Item(_variant_t((long)i+1),
_variant_t((long)startcol)).pdispVal);
vResult = range.get_Value2();
CString strread, stry0, strm0, strd0;
SYSTEMTIME st0;
if (vResult.vt == VT_BSTR) //若是字符串
{
strread = vResult.bstrVal;
}
else if (vResult.vt == VT_R8) //8字节的数字
{
strread.Format(L"%f", vResult.dblVal);
}
else if (vResult.vt == VT_DATE) //时间格式
{
VariantTimeToSystemTime(vResult.date, &st0);
stry0.Format(L"%d", st0.wYear);
strm0.Format(L"%d", st0.wMonth);
strd0.Format(L"%d", st0.wDay);
strread = stry0 + L"-" + strm0 + L"-" + strd0;
}
else if (vResult.vt == VT_EMPTY) //单元为空
{
strread = L"";
}
else if (vResult.vt == VT_I4)
{
strread.Format(_T("%ld"), (int)vResult.lVal);
};
datalist->InsertItem(i , strread);
//插入后面元素
for (int j = startcol+1; j <= colnum; j++)
{
//读取单元格的值
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch(range.get_Item(_variant_t((long)i + 1),
_variant_t((long)j)).pdispVal);
vResult1 = range.get_Value2();
CString str, stry, strm, strd;
SYSTEMTIME st;
if (vResult1.vt == VT_BSTR) //若是字符串
{
str = vResult1.bstrVal;
}
else if (vResult1.vt == VT_R8) //8字节的数字
{
str.Format(L"%f", vResult1.dblVal);
}
else if (vResult1.vt == VT_DATE) //时间格式
{
VariantTimeToSystemTime(vResult1.date, &st);
stry.Format(L"%d", st.wYear);
strm.Format(L"%d", st.wMonth);
strd.Format(L"%d", st.wDay);
str = stry + L"-" + strm + L"-" + strd;
}
else if (vResult1.vt == VT_EMPTY) //单元为空
{
str = L"";
}
else if (vResult1.vt == VT_I4)
{
str.Format(_T("%ld"), (int)vResult1.lVal);
}
//datalist->SetItemText(static_cast<int>(i), static_cast<int>(j),str);
datalist->SetItemText(i-1, j-1, str);
}
}
release();
AfxMessageBox(L"读取成功");
}
和写入时一样,读取完毕后也需要释放资源,我自己定义了一个资源释放函数release(),具体代码如下:
usedrange.ReleaseDispatch();
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
app.Quit();
app.ReleaseDispatch();
至此,mfc读取Excel就已经讲完了,后续会再更新一些简单的Excel样式控制,希望对大家有帮助,谢谢!
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/150537.html原文链接:https://javaforall.cn
相关文章
- C++中this指针的本质
- c++ 字符串流 sstream(常用于格式转换)
- excel宏 java,Microsoft Excel宏运行Java程序
- 彻底搞懂之C++智能指针
- 【笔记】《深入理解C++11》(下)
- linux c++进程间通信_c++多线程通信
- C++构造函数的作用_c++什么是构造函数
- c++ accept_怎么把汇编语言转化为c语言
- C++结构体和类的区别_c++有结构体吗
- C++ 数组
- [C++STL教程]2.queue队列容器,小白都能看懂的讲解!
- 【C++】C++ 入门
- Rust 正在「吞噬」我们的系统,C/C++ 是时候下课了
- C++11类型转换
- 报表 MySQL导出Excel数据报表的指南(mysql导出excel)
- C++中Cstring使用小结详解编程语言
- C++构造函数和析构函数(详解版)
- 文件Linux下如何打开Excel文件(linux打开excel)
- 数据库的比较深入比较:Excel与MySQL的数据库技术优劣(excel与mysql)
- MySQL快速导入Excel数据(mysql导入excel数据)
- excel数据分析:SPSS、MySQL和Excel(spssmysql)
- 极速提升业务效率:利用Excel快速导入Oracle数据库(excel数据导入oracle)
- 轻松操作:oracle快速导入Excel数据(oracle导入excel数据)
- MYSQL与EXCEL:实现数据管理的双重力量(mysql与excel)
- 轻松导出:用SQL Server批量将数据导出到Excel(sqlserver导出excel)
- Excel与Oracle无缝连接,极致解决数据融合问题(excel连oracle)
- 实现Redis数据批量导出至Excel(redis 转excel)
- 基于C++内存分配、函数调用与返回值的深入分析
- C++变位词问题分析
- C++求逆序对的方法