4

目前我有以下代码:

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;
}

但是上面的实现恰好很慢..

任何想法如何以更有效的方式倾倒阵列?

4

3 回答 3

2

虽然所有关于计算和可见性的答案都是正确的,但它们缺少一个关键部分:您正在迭代数据,而不是分别更新每个单元格。这很慢,因为每次都必须进行 com 呼叫。最好有一个分配给匹配范围的二维数组。

像这样工作:定义您的二维数组将您的范围对象设置为匹配的大小(行数/列数)将您的数组分配给范围对象:range.value=2darray 完成!

这种技术适用于 .net 和 c# - 我不知道如何在 C++ 中构建它,抱歉!

也就是说:与您的解决方案相比,它会很快 - 但是,特别是对于大文件,它仍然会很慢 - 最好使用 excel 库。

于 2013-02-18T14:13:01.307 回答
2

您可以通过应用以下技术显着提高性能:

  1. 在更新突发期间禁用事件:

    pXL->EnableEvents = VARIANT_FALSE;
    // update burst here
    pXL->EnableEvents = VARIANT_TRUE;
    
  2. 禁用格式条件计算:

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

AFAIK 第二个选项仅适用于从版本 12 开始的 Excel。您可以通过调用属性从 Excel 中检索版本pXL->Version

于 2013-02-18T13:28:20.437 回答
1

这里有两个主要的杠杆来提高性能:

  1. 禁用计算:(pXL->Calculation=-4135并使用 -4105 重置)

  2. 每次对单元格的读取和写入都需要一些开销。因此,将所有数据复制到一个数组中,在其中处理数据,然后一次将其写回,效率会更高。

于 2013-02-18T13:27:34.400 回答