目前我有以下代码:
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;
}
但上述实施恰好很慢..
如何以更有效的方式灌注数组?
答案 0 :(得分:2)
通过应用以下技术,您可以非常显着地提高性能:
在更新突发期间禁用事件:
pXL->EnableEvents = VARIANT_FALSE;
// update burst here
pXL->EnableEvents = VARIANT_TRUE;
禁用格式限制计算:
sheet_->EnableFormatConditionsCalculation = VARIANT_FALSE;
// update burst here
sheet_->EnableFormatConditionsCalculation = VARIANT_TRUE;
AFAIK第二个选项仅适用于从版本12开始的Excel。您可以通过调用属性pXL->Version
答案 1 :(得分:2)
虽然所有关于计算和可见性的问题都是正确的,但它们缺少一个关键部分: 您正在迭代您的数据,而不是单独更新每个单元格。这很慢,因为每次必须进行com调用。最好有一个2D阵列,它被分配到匹配的范围。
的工作方式如下: 定义你的2D阵列 将范围对象设置为匹配的大小(cols的行数/数量) 将数组分配给范围对象:range.value = 2darray 完成了!
这种技术适用于.net和c# - 我不知道如何用C ++构建它,对不起!
说:与你的解决方案相比,它会很快 - 但是,特别是对于大文件,它仍然会很慢 - 使用excel库会更好。
答案 2 :(得分:1)
这里有两个改善绩效的主要杠杆:
禁用计算:pXL->Calculation=-4135
(并使用-4105重置)
每次读取和写入单元格都需要一些开销。因此,将所有数据复制到数组,在那里处理数据然后一匆忙地将其写回来效率要高得多。