1.导入Excel类型库
使用Visual C++的扩展指令#import导入Excel类型库:
01 | #import "C:\\Program Files\\Common Files\\microsoft shared\\OFFICE14\\MSO.DLL" \ |
02 | rename ( "RGB" , "MsoRGB" ) \ |
03 | rename ( "SearchPath" , "MsoSearchPath" ) |
05 | #import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB" |
07 | #import "C:\\Program Files\\Microsoft Office\\Office14\\EXCEL.EXE" \ |
08 | rename ( "DialogBox" , "ExcelDialogBox" ) \ |
09 | rename ( "RGB" , "ExcelRGB" ) \ |
10 | rename ( "CopyFile" , "ExcelCopyFile" ) \ |
11 | rename ( "ReplaceText" , "ExcelReplaceText" ) \ |
12 | exclude( "IFont" , "IPicture" ) no_dual_interfaces |
#import指令会从指定的可执行文件,动态链接库等COM组件中导出类型库(type lib),在Debug和Release临时目录中生成对应的类型库头文件(type lib header file),以供C++程序使用。如以上三条指令在编译后会生成excel.tlh, mso.lh和vbetext.olb三个头文件,可以在Debug和Release目录中找到。
2.访问Excel暴露的COM对象
下面是一段比较完整的访问Excel的实例代码。首先用生成的数据填充单元格,然后用这些单元格的数据生成了一个图表(Chart):
03 | Excel::_ApplicationPtr pExcelApp; |
04 | HRESULT hr = pExcelApp.CreateInstance(L "Excel.Application" ); |
05 | ATLASSERT(SUCCEEDED(hr)); |
06 | pExcelApp->Visible = true ; |
08 | Excel::_WorkbookPtr pWorkbook = pExcelApp->Workbooks->Open(lpszPathName); |
09 | Excel::_WorksheetPtr pWorksheet = pWorkbook->ActiveSheet; |
10 | pWorksheet->Name = L "Chart Data" ; |
11 | Excel::RangePtr pRange = pWorksheet->Cells; |
13 | const int nplot = 100; |
14 | const double xlow = 0.0, xhigh = 20.0; |
15 | double h = (xhigh-xlow)/( double )nplot; |
16 | pRange->Item[1][1] = L "x" ; |
17 | pRange->Item[1][2] = L "f(x)" ; |
18 | for ( int i=0;i<nplot;++i) |
21 | pRange->Item[i+2][1] = x; |
22 | pRange->Item[i+2][2] = sin (x)* exp (-x); |
25 | Excel::RangePtr pBeginRange = pRange->Item[1][1]; |
26 | Excel::RangePtr pEndRange = pRange->Item[nplot+1][2]; |
27 | Excel::RangePtr pTotalRange = |
28 | pWorksheet->Range[(Excel::Range*)pBeginRange][(Excel::Range*)pEndRange]; |
29 | Excel::_ChartPtr pChart = pExcelApp->ActiveWorkbook->Charts->Add(); |
33 | (Excel::Range*)pTotalRange, |
34 | ( long )Excel::xlXYScatter, |
36 | ( long )Excel::xlColumns, |
41 | pChart->Name = L "My Data Plot" ; |
43 | pWorkbook->Close(VARIANT_TRUE); |
46 | catch (_com_error& error) |
49 | ATLTRACE2(error.ErrorMessage()); |
在这段代码中,Excel::_ApplicationPtr , Excel::_WorkbookPtr 和 Excel::_WorksheetPtr 等均是Visual C++ 编译器根据#import指令自动生成的智能指针,实际上就是C++模板类_com_ptr_t<T>的typedef,其定义可在excel.tlh等类型库头文件中找到。
另外,由于#import指令中没有指定raw_interface_only修饰符,Visual C++对Excel的COM接口进行了适当的封装,以简化COM接口属性和方法的调用,并且将HRESULT返回值都转换成了C++异常,因此,上面的这段代码不需要每一步都坚持HRESULT,而是改为捕获C++异常。