MFC操作excel的一点心得

废话不多说,先把步骤列下

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. 编译过程中可能还会有一些错误,但这些都可以直接在网上找到,很容易解决,这里就不赘述了

展开阅读全文

没有更多推荐了,返回首页