【问题标题】:How to speed up writing onto google spreadsheet如何加快写入谷歌电子表格的速度
【发布时间】:2021-12-30 21:21:59
【问题描述】:

我正在尝试为 google 电子表格编写一个附加组件,该电子表格需要一个 csv 并写入一个新工作表。问题是 csv 可能非常大,达到大约一百万行。我设法通过删除不必要的列来解决单元格限制问题,但我的脚本即使在 500,000 行时也会超时。所以我想知道是否有办法提高写入速度?

这是我创建一个新工作表并使用 csv 数据填充它的代码:

function writeDataToSheet(data,sheetName) {
  const ss = SpreadsheetApp.getActive();
  const sheet = ss.insertSheet(sheetName);
  const neededColumns = data[0].length;
  const totalColumns = sheet.getMaxColumns();
  const columnsToDelete = totalColumns - neededColumns;
  if(columnsToDelete > 0) sheet.deleteColumns(totalColumns , columnsToDelete);
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
  return sheet.getName();
}

需要明确的是,数据应该是一个二维数组,使用Utilities.parseCsv()从csv数据转换而来。

【问题讨论】:

  • 您应该记住,单个电子表格文件的单元格限制约为 500 万个。因此,如果您的文件有超过 5 列、100 万行,那么它可能会失败。
  • 看起来你正在尽可能快地写作。但我建议您重新考虑将数据放入数据库。
  • 我只是在想,你有这么多数据,电子表格不是它的最佳容器。
  • 尝试使用console.time 对每一行进行计时。如果 setValues/delete columns 很慢,您可以使用高级 Google services/sheets api。
  • 官方仍然是 500 万:support.google.com/drive/answer/37603,但是 Google 可能会推出新的更高限制,这很值得一看。感谢您的提醒:)

标签: google-apps-script google-sheets google-sheets-api


【解决方案1】:

在我测量的基准测试中,当数据量很大时,当使用 Sheets API 代替电子表格服务 (SpreadsheetApp) 时,可以降低流程成本。 Ref 无论有没有 V8 运行时,这种情况几乎相同。这已经在TheMaster's comment 中提到过。在您的脚本中,当使用 Sheets API 时,它变为如下。

在使用此修改后的脚本之前,please enable Sheets API at Advanced Google services

修改脚本一:

在此修改中,使用您的data。请按如下方式修改您的脚本。

发件人:

sheet.getRange(1, 1, data.length, data[0].length).setValues(data);

收件人:

Sheets.Spreadsheets.Values.update({values: data}, ss.getId(), sheet.getSheetName(), {valueInputOption: "USER_ENTERED"});

修改脚本2:

本次修改,从To be clear, data is supposed to be a 2 dimensional array, converted from csv data using Utilities.parseCsv().开始,直接使用data之前的CSV数据。请按如下方式修改您的脚本。所以,请直接把csvData放到下面的请求中。

发件人:

sheet.getRange(1, 1, data.length, data[0].length).setValues(data);

收件人:

function writeDataToSheet(csvData, sheetName) {
  const ss = SpreadsheetApp.getActive();
  const sheet = ss.insertSheet(sheetName);
  const requests = { requests: [{ pasteData: { data: csvData, coordinate: { sheetId: sheet.getSheetId() } } }] };
  Sheets.Spreadsheets.batchUpdate(requests, ss.getId());
}

参考资料:

【讨论】:

  • 抱歉回复晚了,过年了。感谢您的回答,看起来很有希望。我会试试看效果如何。
  • @Josee 感谢您的回复。没问题。当我的回答有用时,我很高兴。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 2013-12-25
  • 1970-01-01
  • 2020-05-30
  • 2011-09-28
  • 1970-01-01
相关资源
最近更新 更多