C++ read and write Excel implementation method

  • 2020-04-01 23:39:58
  • OfStack

1. Import Excel type library
Import Excel type library using Visual C++ extension instruction #import:

#import "C:\Program Files\Common Files\microsoft shared\OFFICE14\MSO.DLL"  
    rename("RGB","MsoRGB")  
    rename("SearchPath","MsoSearchPath") 

#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" 

#import "C:\Program Files\Microsoft Office\Office14\EXCEL.EXE"  
    rename( "DialogBox", "ExcelDialogBox" )  
    rename( "RGB", "ExcelRGB" )  
    rename( "CopyFile", "ExcelCopyFile" )  
    rename( "ReplaceText", "ExcelReplaceText" )  
    exclude( "IFont", "IPicture" ) no_dual_interfaces 

The #import directive will export the type lib from the specified executable file, dynamic link library and other COM components, and generate the corresponding type lib header file in the Debug and Release temporary directories for use by C++ programs. If the above three instructions are compiled, they will generate three header files, excel. TLH, mso.lh and vbetext.olb, which can be found in the Debug and Release directories.
2. Access the COM object exposed by Excel
The following is a more complete example of access to Excel code. The cells are first filled with the generated data, and then a Chart is generated with the data from these cells:

try
{ 
    Excel::_ApplicationPtr pExcelApp; 
    HRESULT hr = pExcelApp.CreateInstance(L"Excel.Application"); 
    ATLASSERT(SUCCEEDED(hr)); 
    pExcelApp->Visible = true;   // make Excel's main window visible 

    Excel::_WorkbookPtr pWorkbook = pExcelApp->Workbooks->Open(lpszPathName);  // open excel file 
    Excel::_WorksheetPtr pWorksheet = pWorkbook->ActiveSheet; 
    pWorksheet->Name = L"Chart Data"; 
    Excel::RangePtr pRange = pWorksheet->Cells; 

    const int nplot = 100; 
    const double xlow = 0.0, xhigh = 20.0; 
    double h = (xhigh-xlow)/(double)nplot; 
    pRange->Item[1][1] = L"x";  // read/write cell's data 
    pRange->Item[1][2] = L"f(x)"; 
    for (int i=0;i<nplot;++i) 
    { 
        double x = xlow+i*h; 
        pRange->Item[i+2][1] = x; 
        pRange->Item[i+2][2] = sin(x)*exp(-x); 
    } 

    Excel::RangePtr pBeginRange = pRange->Item[1][1]; 
    Excel::RangePtr pEndRange = pRange->Item[nplot+1][2]; 
    Excel::RangePtr pTotalRange =  
        pWorksheet->Range[(Excel::Range*)pBeginRange][(Excel::Range*)pEndRange]; 
    Excel::_ChartPtr pChart = pExcelApp->ActiveWorkbook->Charts->Add(); 
    // refer to : 
    // http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.chart.chartwizard(v=vs.80).aspx 
    pChart->ChartWizard( 
        (Excel::Range*)pTotalRange, 
        (long)Excel::xlXYScatter, 
        6L, 
        (long)Excel::xlColumns, 
        1L,1L, 
        true, 
        L"My Graph", 
        L"x",L"f(x)"); 
    pChart->Name = L"My Data Plot"; 

    pWorkbook->Close(VARIANT_TRUE);  // save changes 
    pExcelApp->Quit(); 
} 
catch (_com_error& error) 
{ 
    ATLASSERT(FALSE); 
    ATLTRACE2(error.ErrorMessage()); 
}

In this code, Excel::_ApplicationPtr, Excel::_WorkbookPtr, and Excel::_WorksheetPtr are all smart Pointers automatically generated by the Visual C++ compiler according to the #import directive, which is actually the C++ template class _com_ptr_t < T > The definition of a typedef can be found in a type library header file such as excel. TLH.
In addition, since the #import directive does not specify the raw_interface_only modifier, Visual C++ appropriately encapsulates the COM interface of Excel to simplify the invocation of COM interface properties and methods, and converts the return value of HRESULT to C++ exceptions. Therefore, the code above does not need to insist on HRESULT at every step, but instead catches C++ exceptions.

Related articles: