预期实现结果:
C++可对Excel表精确进行某一行某一列的增加、修改、删除、查询数据
预演环境:
Window7+VS2013+office2013(32位)、2010(64位)、2007(64位)2003(64位)+WPS2016(位)
预演方法:
1、 ODBC方式访问
2、 通过解析Excel表格文件
3、 通过OLE/COM方式访问
可行性分析:
2003版本office办公软件创建Excel表的后缀.xls 而以后的高版本创建表后缀为.xlsx。是用新的基于XML的压缩文件格式取代了其目前专有的默认文件格式,在传统的文件名扩展名后面添加了字母x(即.docx取代.doc、.xlsx取代.xls,等等),使其占用空间更小,可以向下兼容xls。
这样造成以前通过ODBC方式访问和通过解析Excel表格文件的方法代表无法解析高版本的xlsx文件,因此选择OLE/COM方式访问可以一劳永逸的解决所有的版本问题。**
OLE/COM方式访问步骤:
1. 新建MFC工程
2. 配置工程,添加组件类接口
导入OLE/COM组件的接口的步骤为:项目->类向导->添加类->类型库中的MFC类,先选择要导入的组件所在的路径,即Excel.exe所在的路径。导入接口中所用到类方法接口如下图所示:
3. 将各个导入的头文件“#import “C:\Program Files\Microsoft Office\Office12\EXCEL.EXE” no_namespace中部分注释掉。在:#include <、afxdisp.h>加入上面7个头文件文件
4.代码实现
-
在对话框Dlg.h定义接口变量
CApplication app; CWorkbook book; CWorkbooks books; CWorksheet sheet; CWorksheets sheets; CRange range; CRange cols; LPDISPATCH lpDisp;
对话框中拖拽两个按钮,分别命名为导入和导出
-
实现导入导出的功能
导入:
void CCpp_ExcleDemoDlg::OnBnClickedButton1() { COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); if (!app.CreateDispatch(_T("Excel.Application"))) { this->MessageBox(_T("无法创建Excel应用!")); } books = app.get_Workbooks(); //打开Excel,其中pathname为Excel表的路径名 lpDisp = books.Open(_T("D:\\工作簿1.xlsx"), covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional); book.AttachDispatch(lpDisp); sheets = book.get_Worksheets(); sheet = sheets.get_Item(COleVariant((short)1)); //获得坐标为(A,1)的单元格 range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("A1"))); //获得单元格的内容 COleVariant rValue; rValue = COleVariant(range.get_Value2()); //转换成宽字符 rValue.ChangeType(VT_BSTR); //转换格式,并输出 this->MessageBox(CString(rValue.bstrVal)); book.put_Saved(TRUE); app.Quit(); }
导出:
void CCpp_ExcleDemoDlg::OnBnClickedButton2()
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
if (!app.CreateDispatch(_T("Excel.Application")))
{
this->MessageBox(_T("无法创建Excel应用!"));
}
books = app.get_Workbooks();
//打开Excel,其中pathname为Excel表的路径名
book = books.Add(covOptional);
sheets = book.get_Worksheets();
sheet = sheets.get_Item(COleVariant((short)1)); //获得坐标为(A,1)和(B,1)的两个单元格
range = sheet.get_Range(COleVariant(_T("A1")), COleVariant(_T("B1"))); //设置单元格类容为Hello Exce
range.put_Value2(COleVariant(_T("Clear Excel Demo"))); //选择整列,并设置宽度为自适应
cols = range.get_EntireColumn();
cols.AutoFit();
//获得坐标为(C,2)单元格
range = sheet.get_Range(COleVariant(_T("C2")), COleVariant(_T("C2")));
//设置公式“=RAND()*100000”
range.put_Formula(COleVariant(_T("=RAND()*100000")));
//设置数字格式为货币型
range.put_NumberFormat(COleVariant(_T("$0.00")));
//选择整列,并设置宽度为自适应
cols = range.get_EntireColumn();
cols.AutoFit();
//显示Excel表
app.put_Visible(TRUE);
app.put_UserControl(TRUE);
}
Demo代码功能概述:
Demo实现对某一行某一列数据进行读取、准确输入某一行某一列
OLE/COM方式编程注意事项
有错误error C2059双击error C2059,将VARIANT DialogBox()改成VARIANT _DialogBox()再次编译,则可以通过