请选择 进入手机版 | 继续访问电脑版

MFC读写Excel操作

[复制链接]
苍野狼步 发表于 2020-12-31 18:59:52 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
前言

现在遇到特别的需求,需要将Excel中的数据提出,通过算法处置惩罚,然后将数据写会Excel。所以这篇文章,就主要来做这件事情。
参考博客:

博客1  :读Excel,写Excel,获取驱动。基于win32控制台写的。
博客2 :  读Excel,写Excel,获取驱动。基于MFC写的。该项目是多字符集,没有做多字符集与Unicode的转码。
官网API  这是官网的API可以参考
多字符转Unicode   我的程序是基于VS2010MFC开发的,Unicode项目,所以用到宽字符与多字符的转换。
特别感谢 蓝朋友的技能支持(我们有共同的语言——C++)。
下面分三部分先容:

  • 创建一个Excel表格,然后写入表头和示例,下载下来,这种表作为数据的模板,提供给用户。
  • 用户拿到模板,填好数据,然后MFC程序打开,读取数据,并举行盘算。盘算好之后,继承用第一步的方法,将数据填入Excel表格。然后下载。
  • 当此程序移植到其他人电脑时,需要自动获取其他电脑的Excel驱动。
1、创建Excel并插入数据

  1. // 下载模板void CtestMFCDlg::OnBnClickedBtnDownload(){        CString sDriver = L"MICROSOFT EXCEL DRIVER (*.XLS)";//直接写上驱动名称        //sDriver = GetExcelDriver();// 也可以用这个函数获取驱动名称        CString sExcelFile; // Excel表格名称        CString sPath;   // 文件路径        CString sSql;            CDatabase database;        //获取主程序exe所在路径,存在sPath中         GetModuleFileName(NULL,sPath.GetBufferSetLength (MAX_PATH+1),MAX_PATH);         sPath.ReleaseBuffer ();         int nPos;         nPos=sPath.ReverseFind ('\\'); // exe程序的上一级路径        sPath=sPath.Left (nPos + 1); // sPath 是exe程序的上一级路径    // 打开名为:模板.xls  的文件,如果没有,就会新建一个,并打开它。以备背面插入数据        CFileDialog fDlg(TRUE, _T("xls"), sPath + "模板.xls",                 OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("xlsx File (*.xls)|*.xls|") );         if(fDlg.DoModal() != IDOK)                return;        sExcelFile = fDlg.GetPathName(); //获取 新的模板excel 的路径        TRY        {                sSql.Format(L"DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB="%s";DBQ=%s",sDriver, sExcelFile, sExcelFile);                if (database.OpenEx(sSql, CDatabase::noOdbcDialog))                {                        // 创建表头                        sSql = "CREATE TABLE demo (姓名 TEXT,学号 TEXT,性别 TEXT,班级 TEXT,志愿 TEXT)";                        database.ExecuteSQL(sSql);            // 每执行一行sSql,就需要执行ExecuteSQL一次,否则Excel中只有最后一次数据,这个坑,我踩过了                        sSql = "INSERT INTO demo (姓名,学号,性别,行政班级,最终志愿) VALUES "                                "('王二小','1123201821','男','行政1班','物化生')";                        database.ExecuteSQL(sSql);                        sSql = "INSERT INTO demo (姓名,学号,性别,行政班级,最终志愿) VALUES "                                "('王三小','1123201822','女','行政2班','物化史')";                        database.ExecuteSQL(sSql);                        sSql = "INSERT INTO demo (姓名,学号,性别,行政班级,最终志愿) VALUES "                                "('王四小','1123201823','女','行政3班','物生地')";                        database.ExecuteSQL(sSql);                        sSql = "INSERT INTO demo (姓名,学号,性别,行政班级,最终志愿) VALUES "                                "('王五小','1123201824','男','行政4班','化生史')";                        database.ExecuteSQL(sSql);                }                // 关闭数据库                database.Close();        }        CATCH_ALL(e)        {                TRACE1("Excel驱动没有安装: %s",sDriver);        }        END_CATCH_ALL;}
复制代码
2、打开Excel并读取数据

  1. void CtestMFCDlg::OnBnClickedBtnInput(){        // 获取文件名         CFileDialog fDlg(TRUE, _T("xls"), NULL,                  OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("xlsx File (*.xls)|*.xls|") );          if(fDlg.DoModal() != IDOK)                 return;         CString sFilename = fDlg.GetPathName();        // 开始吸收Excel中的数据        CDatabase database;        CString sql;// sql语句        CString sDsn;        CString sDriver = L"Microsoft Excel Driver (*.XLS)";// 驱动                stuInfo studentInfo;// 单个学生的信息        CString item1, item2, item3,item4,item5;        if (sDriver.IsEmpty())        {                MessageBox(L"驱动安装失败");                return;        }        TRY         {                sDsn.Format(L"ODBC;DRIVER={%s};DSN='''';DBQ=%s",sDriver,sFilename);                if(database.Open(NULL, FALSE, FALSE, sDsn))                {                        CRecordset recset(&database);                        //sql = L"SELECT '姓名','学号','性别','行政班级','最终志愿' FROM demo";// 字太多,不乐成                        //sql = L"SELECT * FROM Sheet1";// 无法识别Sheet1,纵然将Sheet1表挪移到第一个位置。demo表纵然在第二个位置,也能被识别                        //sql = L"SELECT * FROM demo";                        sql = L"SELECT 姓名,学号,班级,志愿,性别 FROM demo";                                    recset.Open(CRecordset::forwardOnly,sql,CRecordset::readOnly);                        while(!recset.IsEOF())                        {                                // 乐成                                 recset.GetFieldValue(L"姓名",item1);                                recset.GetFieldValue(L"学号",item2);                                 recset.GetFieldValue(L"班级",item3);                                 recset.GetFieldValue(L"志愿",item4);                                recset.GetFieldValue(L"性别",item5);                                                                TRACE(L"姓名:%s, 学号:%s, 性别:%s,班级:%s, 志愿:%s\n", item1,item2,item3,item4,item5);// 用于控制台输出                                                //移动到下一行                //这一行遇到过很神奇的问题:只读了第一行,背面的就直接跳过了。还没找到原因。                                recset.MoveNext();                        }                        database.Close();                }                                        }        CATCH (CMemoryException, e)        {                TRACE1("Excel驱动没有安装: %s",sDriver);        }        END_CATCH}
复制代码
3、获取Excel的驱动

GetExcelDriver()获取到Excel驱动

来源:https://blog.csdn.net/qq_34732729/article/details/110671941
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题

专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )