performancegoogle-sheetsgoogle-apps-scriptgoogle-sheets-apiborder

What is the most efficient way to get borders in Google Apps Script


What is the best way to get border details in Google Apps Script?

I cannot see anything with borders in the documentation for GAS, so I have had to resort to getting borders through the Spreadsheet API.

This works ok, other than when the number of borders gets large where it will take a long time to return, or not return at all.

Is there a better way to do this?

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

Solution

  • If my understanding is correct, how about this workaround? In this workaround, I request directly to the endpoint of Sheets API for retrieving the borders.

    Workaround:

    Sample situation

    In this sample script, as a sample situation, I supposes the default sheet which has 26 columns x 1000 rows, and the borders are set to all cells.

    Sample script 1:

    In this sample script, the borders are retrieved by one API call.

    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());
    
    Result:

    Sample script 2:

    In this sample script, the borders are retrieved with the asynchronous process by several API calls.

    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: []}]}]});
    
    Result:

    When the sample script 2 was used, the following results were obtained.

    But if the number of requests in one run are increased, the error related to the over of quotas occurs. Please be careaful this.

    Note:

    References: