angular - Office.js : Increasingly poorer performance writing a large amount of rows to Excel

标签 angular office-js excel-2016

我有大约 100 列宽的行,但我只想写入大约 8000 行。当我写出 3000 行(每批 500 行)时,它始终以每 500 行大约 2-3 秒的速度写入。

但是,当我尝试写出包含 8000 行相似数据(更多列)的更大数据集时,它对于前 3000 行(每 500 行大约 3-4 秒)表现良好,但是从第 2500 -3000 行左右开始,性能变得越来越慢,Excel 变得缓慢。例如:

write rows address:  Sheet1!A3:DC502
batch write time:    3.0766400244386167  seconds
write rows address:  Sheet1!A503:DC1002
batch write time:    3.3348399202363796  seconds
write rows address:  Sheet1!A1003:DC1502
batch write time:    3.7307800745354034  seconds
write rows address:  Sheet1!A1503:DC2002
batch write time:    4.149179874582915  seconds
write rows address:  Sheet1!A2003:DC2502
batch write time:    3.8166401331085944  seconds
write rows address:  Sheet1!A2503:DC3002
batch write time:    7.215600102149649  seconds
write rows address:  Sheet1!A3003:DC3502
batch write time:    31.93173993128445  seconds
write rows address:  Sheet1!A3503:DC4002
batch write time:    95.68281983804563  seconds
write rows address:  Sheet1!A4003:DC4502
batch write time:    148.84947986377625  seconds
write rows address:  Sheet1!A4503:DC5002
batch write time:    203.41412001861877  seconds
write rows address:  Sheet1!A5003:DC5502
batch write time:    270.2974798251381  seconds
write rows address:  Sheet1!A5503:DC6002
...

前 30 列左右包含公式,并且单元格中具有条件格式。其余的只是将数据写入普通的白色单元格。我只是使用 range.values 将数据交给 excel,这就是花了这么长时间的原因。 如何才能获得稳定的性能?

这是我的代码:

async writeRows(data, formulas, sheetName, startCol, startRow) {
  return await Excel.run(async (ctx) => {
    let sheet = ctx.workbook.worksheets.getItem(sheetName);
    let endRow = startRow;
    let startRowOffset = startRow;
    let batchSize = 500;
    for (let i = 0; i < data.length; i = i + batchSize) {
      let t0 = performance.now();
      let min = Math.min(batchSize, data.length - i);
      let endCol = intToColumn(data[0].length);
      startRow = startRowOffset + i;
      endRow = startRow + min - 1;
      let address = sheetName + "!" + startCol + startRow + ":" + endCol + endRow;
      console.log("write rows address: ", address);
      let range = sheet.getRange(address);
      ctx.application.suspendApiCalculationUntilNextSync();
      range.values = data.slice(i, i + min)
      range.formulas = formulas.slice(i, i + min);
      await ctx.sync();
      let t1 = performance.now();
      console.log("batch write time: ", (t1 - t0) / 1000, ' seconds');
    }
    return endRow;
  });
}

如果您认为这只是繁重的公式,那么现在是运行相同行而不向 range.formulas 分配任何内容的时候了:

batch write time:  2.072960040280297  seconds
batch write time:  1.893160016976646  seconds
batch write time:  2.239300093637197  seconds
batch write time:  2.4051598865728154  seconds
batch write time:  2.4535400113378855  seconds
batch write time:  4.228719875053808  seconds
batch write time:  21.932359953223656  seconds
batch write time:  65.58508005044697  seconds
batch write time:  99.76420028338683  seconds
batch write time:  133.58046007197566  seconds
batch write time:  181.46535997193905  seconds
...

这是任务管理器的屏幕截图:

enter image description here

有什么想法吗?

最佳答案

循环内有一个ctx.sync。这可能会成为性能 killer 。尝试重构该方法,以便它通过一次同步写入所有内容。看看我对这个问题的回答中的模式可能会有所帮助:Document not in sync after replace text .

关于angular - Office.js : Increasingly poorer performance writing a large amount of rows to Excel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49545976/

相关文章:

javascript - 在 TypeScript 函数内使用外部变量。

javascript - Excel for Windows 中的开发工具控制台

office365 - outlook 身份 token 无效

angular2 中的 httpParamSerializerJQLike?

angular - 类型错误 : this. root_ 为空

outlook-addin - 如何在通过rest API 上传附件后刷新Outlook 撰写窗口?

VBA 错误处理不适用于 Excel 2016 中的一位用户

excel - 将范围复制到另一张纸

c# - 如何从 Excel 中获取范围(打印区域)?

javascript - ASP.NET Core 2.0 Razor + Angular 4 混合