【问题标题】:What is the most efficient way to get borders in Google Apps Script在 Google Apps 脚本中获取边框的最有效方法是什么
【发布时间】:2019-05-09 08:54:39
【问题描述】:

在 Google Apps 脚本中获取边框详细信息的最佳方法是什么?

我在 GAS 的文档中看不到任何带有边框的内容,因此我不得不求助于通过电子表格 API 获取边框。

这可以正常工作,除非边框数量变大,需要很长时间才能返回,或者根本不返回。

有没有更好的方法来做到这一点?

var fieldsBorders = 'sheets(data(rowData/values/userEnteredFormat/borders))';

var currSsId = SpreadsheetApp.getActiveSpreadsheet().getId();
var activeSheet = SpreadsheetApp.getActiveSheet();
var name = activeSheet.getName();

var data = Sheets.Spreadsheets.get(currSsId, {
    ranges: name,
    fields: fieldsBorders
});

【问题讨论】:

  • 我认为使用 Sheets API 来检索电子表格中的边框是合适的。那请问when the number of borders gets large where it will take a long time to return, or not return at all.的情况?
  • 举个例子,我在默认的 26 x 1000 电子表格中设置了所有单元格,并尝试使用上述调用获取边框,但它显示的数据过多时超时。
  • 感谢您的回复。在我的环境中,当我为 26 x 1000 单元格设置边框并运行脚本时,处理时间约为 50 秒。那么你能提供复制你的情况的详细流程吗?我想确认一下并考虑您的解决方案或解决方法。
  • 也许它是一张更大的床单,无论哪种方式,50 年代都需要很长时间才能获得边框。对 GAS 的其他调用只需要很短的时间即可完成。你能确认这是获得边界的唯一方法吗?
  • 感谢您的回复。我提出了一个解决方法作为答案。你能确认一下吗?如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

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


【解决方案1】:
  • 您希望降低从电子表格中的工作表中检索边框的过程成本。
  • 当我为 26 x 1000 单元格设置边框并运行脚本时,在我的环境中处理时间约为 50 秒。
    • 对于这种情况,您希望进一步降低成本。
    • 您的回复评论是perhaps it was a bigger sheet it was on, either way 50s is a long time to get the borders. The other calls to GAS take a very small amount of time to complete. Can you confirm this is the only way to get borders?

如果我的理解是正确的,那么这个解决方法怎么样?在此解决方法中,我直接向 Sheets API 的端点请求检索边框。

解决方法:

示例情况

在这个示例脚本中,作为示例情况,我假设默认工作表有 26 列 x 1000 行,并且边框设置为所有单元格。

示例脚本 1:

在此示例脚本中,边框由一个 API 调用检索。

var ss = SpreadsheetApp.getActiveSpreadsheet();
var fileId = ss.getId();
var sheetName = ss.getActiveSheet().getName();
var token = ScriptApp.getOAuthToken();
var fields = "sheets/data/rowData/values/userEnteredFormat/borders";
var params = {
    method: "get",
    headers: {Authorization: "Bearer " +  token},
    muteHttpExceptions: true,
};
var range = sheetName + "!A1:Z1000";
var url = "https://sheets.googleapis.com/v4/spreadsheets/" + fileId + "?ranges=" + encodeURIComponent(range) + "&fields=" + encodeURIComponent(fields); 
var res = UrlFetchApp.fetch(url, params);
var result = JSON.parse(res.getContentText());
结果:
  • 使用示例脚本 1 时,平均处理时间为 2.2 秒。
    • 虽然不清楚Advanced Google Service的Sheets API的内部流程,但发现直接向端点请求时,可以降低流程成本。

示例脚本 2:

在此示例脚本中,通过多个 API 调用使用异步过程检索边框。

var sep = 500; // Rows retrieving by 1 request.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var fileId = ss.getId();
var sheetName = ss.getActiveSheet().getName();
var token = ScriptApp.getOAuthToken();
var fields = "sheets/data/rowData/values/userEnteredFormat/borders";
var requests = [];
var maxRows = 1000;
var row = 1;
for (var i = 0; i < maxRows / sep; i++) {
  var range = sheetName + "!A" + row + ":Z" + (row + sep - 1);
  requests.push({
    method: "get",
    url: "https://sheets.googleapis.com/v4/spreadsheets/" + fileId + "?ranges=" + encodeURIComponent(range) + "&fields=" + encodeURIComponent(fields),
    headers: {Authorization: "Bearer " +  token},
  });
  row += sep;
}
var response = UrlFetchApp.fetchAll(requests);
var result = response.reduce(function(ar, e) {
  var obj = JSON.parse(e.getContentText());
  Array.prototype.push.apply(ar.sheets[0].data[0].rowData, obj.sheets[0].data[0].rowData);
  return ar;
}, {sheets: [{data: [{rowData: []}]}]});
结果:

使用示例脚本2时,得到如下结果。

  • sep 为 500(本例中运行 2 个 API 调用)时,平均处理时间为 1.9 秒。
  • sep 为 200(本例中运行 5 个 API 调用)时,平均处理时间为 1.3 秒。

但是如果一次运行的请求数增加,就会出现配额溢出的错误。请注意这一点。

注意:

  • 这是一个用于测试上述情况的简单示例。所以我认为上面的脚本不能用于所有情况。如果您使用上述示例脚本,请根据您的情况进行修改。

参考资料:

【讨论】:

  • 非常感谢您的详细回复。不幸的是,我下周现在休年假,所以在我回来之前我可能无法正确测试这个,但它看起来确实正是我想要的。如果它可以从 50 直接调用它减少到 2 秒,我会很激动。我真的希望它也可以管理更多的单元格,我有时必须处理 500,000 个单元格的数据,所以即使这需要 10 秒左右并且不会超时,那也很棒。
  • @user3284707 感谢您的回复。虽然我还没有确认50万片左右,但我认为降低成本的方向是一样的。重要的一点是,在测试脚本时,如果单次运行的请求数增加,则会出现与配额超出有关的错误。请注意这一点。
猜你喜欢
  • 2019-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多