简体   繁体   中英

c++ how to export an array to excel

At the moment I have the following code:

int ExportToExcel(short *data, int nof_rows, int nof_cols)
{
      HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);   
      if (FAILED(hr))   
      {  
           cout << "Failed to initialize COM library. Error code = 0x"  << hex << hr << endl;   
           return hr;  
      }  

      Excel::_ApplicationPtr pXL;
      if ( FAILED( pXL.CreateInstance( "Excel.Application" ) ) )  
      {  
           cout << "Failed to initialize Excel::_Application!" << endl;  
           return -1;  
      }  

      Excel::_WorkbookPtr workbook = pXL->Workbooks->Add(Excel::xlWorksheet);
      Excel::_WorksheetPtr pSheet= pXL->ActiveSheet;
      pSheet->Name = "arr_1";

      Excel::RangePtr pRange = pSheet->Cells;  
      for(int i=1; i<=nof_rows; i++)
          for(int j=1;j<=nof_cols; j++)
              pRange->Item[i][j] = *data++; 

      pXL->Visible=true;

      return 0;
}

But the above implementation happens to be very slow..

Any ideas how to pour the array in a more efficient way ?

You can improve the performance very significantly by applying the following techniques:

  1. Disable events during update burst:

     pXL->EnableEvents = VARIANT_FALSE; // update burst here pXL->EnableEvents = VARIANT_TRUE; 
  2. Disable format condictions calculation:

     sheet_->EnableFormatConditionsCalculation = VARIANT_FALSE; // update burst here sheet_->EnableFormatConditionsCalculation = VARIANT_TRUE; 

AFAIK the second option works only for Excel starting from version 12. You can retrieve version from Excel by calling property pXL->Version

While all anwsers about calculation and visibillity are correct, they are missing a critical part: you are iterating through your data and than update every cell seperately. This is slow, because every time a com call has to be done. It is better to have a single 2D-array, which is assigned to a matching range.

that works like this: define your 2d array set your range object to a matching size (rows / number of cols) assign your array to the range object: range.value=2darray done!

This technique works in .net and c# - i have no idea how to build it in C++, sorry!

that said: compared to your solution it will be fast - but, especially for big files, it will still be slow - better to use a excel library.

There are two main levers to improve performance here:

  1. Disable calculation: pXL->Calculation=-4135 (and reset with -4105)

  2. Each reading and writing to cells take some overhead. It is therefore much more efficient to copy all the data to an array, process the data there and then write it back with in one rush.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM