大家好,又见面了,我是你们的朋友全栈君。
前面已经讲过了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样式控制,希望对大家有帮助,谢谢!
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150537.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...