前言
现在遇到特别的需求,需要将Excel中的数据提出,通过算法处置惩罚,然后将数据写会Excel。所以这篇文章,就主要来做这件事情。
参考博客:
博客1 :读Excel,写Excel,获取驱动。基于win32控制台写的。
博客2 : 读Excel,写Excel,获取驱动。基于MFC写的。该项目是多字符集,没有做多字符集与Unicode的转码。
官网API 这是官网的API可以参考
多字符转Unicode 我的程序是基于VS2010MFC开发的,Unicode项目,所以用到宽字符与多字符的转换。
特别感谢 蓝朋友的技能支持(我们有共同的语言——C++)。
下面分三部分先容:
- 创建一个Excel表格,然后写入表头和示例,下载下来,这种表作为数据的模板,提供给用户。
- 用户拿到模板,填好数据,然后MFC程序打开,读取数据,并举行盘算。盘算好之后,继承用第一步的方法,将数据填入Excel表格。然后下载。
- 当此程序移植到其他人电脑时,需要自动获取其他电脑的Excel驱动。
1、创建Excel并插入数据
- // 下载模板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并读取数据
- 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
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |