废话不多说,先把步骤列下
1. 你得安装了microsoft的excel软件,wps是不行的哦 ~ 因为只有ms的excel软件才提供了有关的类库
2. 选中工程,添加类→MFC→Typelib中的MFC类
3. 选中类库, 这里有两种情况,一是可以选中注册表,然后在可用类类型库中选择Microsoft Excel Object Library(据版本有可能细微之不同);二是选择文件然后找到C:\Program Files (x86)\Microsoft Office\Office12\EXCEL..EXE
4. 添加需要使用的接口,根据网上大部分人的说法和能满足我需要的类就只有5个类CApplication, CWorkBook, CWorkSheet, CWorkBooks, CWorkSheets, CRange,选择接口时分别是_Application, _WorkBook, _WorkSheet,, Range, WorkBooks, WorkSheets,选择好后点确定,就会多5个头文件,删除每个头文件里面的开头的“#import "C:\\Program Files (x86)\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace”,不删除则会有莫名其妙编译错误
5. 程序代码示例,以下是代码示例,在自己的项目中使用的,当然也是参考了网上的,输出的是两列N行的表,如果你要测试,自己定义和填充那个变量m_vectPairInfo
void CComponentInfoDlg::OnBnClickedButtonExcel()
{
// TODO: 在此添加控件通知处理程序代码
CApplication exlApp;
CWorkbook exlBook;
CWorkbooks exlBooks;
CWorksheet exlSheet;
CWorksheets exlSheets;
CRange exlRge, usedRange;
if (!exlApp.CreateDispatch(_T("Excel.Application"), NULL))
{
AfxMessageBox(_T("创建Excel服务失败!"));
return;
}
exlApp.put_Visible(TRUE);
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
exlBooks.AttachDispatch(exlApp.get_Workbooks());
exlBook = exlBooks.Add(covOptional);
exlSheets.AttachDispatch(exlBook.get_Sheets(), TRUE);
//添加新的Sheet页面
exlSheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);
//删除第二个Sheet页面
exlSheet.AttachDispatch(exlSheets.get_Item(_variant_t((long)2)),TRUE);
exlSheet.Delete();
//把第一个Sheet页面的名字改变为TestSheet
exlSheet.AttachDispatch(exlSheets.get_Item(_variant_t((long)1)),TRUE);
exlSheet.put_Name(_T("构件属性列表"));
///合并第一行单元格A1至D1//
//加载要合并的单元格
exlRge.AttachDispatch(exlSheet.get_Range(_variant_t("A1"),_variant_t("B1")),TRUE);
exlRge.Merge(_variant_t((long)0));
设置表格内容
exlRge.AttachDispatch(exlSheet.get_Cells(),TRUE);//加载所有单元格
exlRge.put_Item(_variant_t((long)1),_variant_t((long)1),_variant_t("属性表"));
long nRow = 2;
for (std::vector<std::pair<CString, CString> >::const_iterator iter = m_vecPairConInfo.begin(); iter !=m_vecPairConInfo.end(); ++iter)
{
exlRge.put_Item(_variant_t(nRow),_variant_t((long)1),_variant_t(iter->first));
exlRge.put_Item(_variant_t(nRow),_variant_t((long)2),_variant_t(iter->second));
++nRow;
}
exlRge.AttachDispatch(exlSheet.get_UsedRange());//加载已使用的单元格
exlRge.ReleaseDispatch();
exlSheet.ReleaseDispatch();
exlSheets.ReleaseDispatch();
exlBook.ReleaseDispatch();
exlBooks.ReleaseDispatch();
//m_ExlApp一定要释放,否则程序结束后还会有一个Excel进程驻留在内存中,而且程序重复运行的时候会出错
exlApp.ReleaseDispatch();
}
==================================================================
好了,现在我来说下在实现这个功能过程中遇到的问题。
1. 找不到类库,很简单,装个ms的excel就可以了
2. 编译不通过,网上最多的就是那些什么出了一大堆编译错误的,很多解决方法是加什么用rename什么的,实在不需要这样,最直接的方法是去掉每个头文件中的“#import "C:\\Program Files (x86)\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace”,开头这一句
3. 还是有错误,报的是CRange.h的错误,则把其中的DialogBox改成_DialogBox
4. 还是有错误,而且是莫名其妙的错误,这里仅仅是我遇到的问题,搞的我弄了两天的时间,非常的郁闷,由于我用的是vs2005,经过了上述操作以后,错误也被我在网上差不多都找了一遍,还是没有结果,后来回家用自己的vs2010重新弄了一个MFC工程,自己重新搞了一遍,发现虽然有错误,但简单修改一下就直接成功了,后来回到公司,用vs2005重复步骤,还是失败,气死我了!再后来我横下心来再在公司机器上用vs2010又搞了一遍,发现又没有问题,最后才发现,2005和2010使用的头文件虽然名字都一样,带CRange.h里面的内容居然不同,后来我就直接用vs2010上的文件复制到vs2005的工程里面,发现也直接能用了,坑爹啊!至于原因,我也不清楚为什么,但这真是个很无语的错误,希望可以补足那些和我遇到同样问题的人。
5. 一些实用技巧,5个头文件显得有些笨拙,我后来把这五个文件的内容都复制到了一个文件中,取名为"CExcelApplication.h",并用名空间包含,以防以后使用word类库时候的冲突。
6. 编译过程中可能还会有一些错误,但这些都可以直接在网上找到,很容易解决,这里就不赘述了