Updating Spreadsheets

Aside from the data contained in its cells, a spreadsheet includes many other types of data, such as:

  • Cell formats
  • Cell borders
  • Named ranges
  • Protected ranges
  • Conditional formatting

These are just some of the many kinds of data that control the appearance and operation of a spreadsheet. The batchUpdate method lets you update any of these spreadsheet details. Changes are grouped together in a batch so that if one request fails, none of the other (potentially dependent) changes is written.

Categories of operation

The particular operations supported by batchUpdate can be grouped into the following broad categories:

Category Description
Add (and Duplicate)Add new objects (sometimes based on old ones, as in the Duplicate requests).
Update (and Set)Update certain properties of an object, usually leaving the old properties alone (whereas Set requests will overwrite the prior data).
DeleteRemove objects.

These categories are used in the next section to describe the behavior of specific operations.

Batch update operations

The batchUpdate method works by taking one or more Request objects, each one specifying a single kind of request to perform. There are many different kinds of requests. Here's a breakdown on the types of requests, grouped into different categories.

Object ADD / DUPLICATE UPDATE / SET DELETE
Spreadsheet Properties UpdateSpreadsheetPropertiesRequest
Sheets AddSheetRequest
DuplicateSheetRequest
UpdateSheetPropertiesRequest DeleteSheetRequest
Dimensions (including their properties) InsertDimensionRequest
AppendDimensionRequest
UpdateDimensionPropertiesRequest
MoveDimensionRequest
AutoResizeDimensionsRequest
DeleteDimensionRequest
Cells (including values, formats, data validation, etc.) RepeatCellRequest
UpdateCellsRequest
AppendCellsRequest
Named Ranges AddNamedRangeRequest UpdateNamedRangeRequest DeleteNamedRangeRequest
Borders UpdateBordersRequest
Filters (filter views & the basic filter) AddFilterViewRequest
DuplicateFilterViewRequest
UpdateFilterViewRequest
SetBasicFilterRequest
ClearBasicFilterRequest
Data Validation SetDataValidationRequest
Conditional Format Rules AddConditionalFormatRuleRequest UpdateConditionalFormatRuleRequest DeleteConditionalFormatRuleRequest
Protected Ranges AddProtectedRangeRequest UpdateProtectedRangeRequest DeleteProtectedRangeRequest
Embedded Objects (including charts) AddChartRequest UpdateChartSpecRequest
UpdateEmbeddedObjectPositionRequest
DeleteEmbeddedObjectRequest
Merges MergeCellsRequest UnmergeCellsRequest

There are also some additional requests that mimic user actions for manipulating data:

Field masks

Many of the "Update" requests require field masks. These are a comma-delimited list of fields that you want to update. The mask is required to make sure only fields you want to edit are updated. You can use a "*" as short-hand for updating every field (which means a field may revert to its default state if you don't specify a value for it in the request).

For example, to update just the Title of a spreadsheet, this would be the request:

Request:

POST .../v4/spreadsheets/spreadsheetId:batchUpdate

Request body:

{
  "requests": [{
      "updateSpreadsheetProperties": {
          "properties": {"title": "My New Title"},
          "fields": "title"
      }
  }]
}

Responses

When updating a spreadsheet, some kinds of requests may return responses. These are returned in an array, with each response occupying the same index as the corresponding request. Some requests do not have responses. For those requests, the response will be empty.

Typically the "Add" requests will have responses, so that you know information (such as the ID) of the newly added object. See Response for the list of supported responses.

Example

The example below performs the following actions:

  1. Updates the spreadsheet's title using the title variable.
  2. Finds and replaces cell values in the spreadsheet using the find and replacement variables.

Apps Script

sheets/api/spreadsheet_snippets.gs
// This code uses the Sheets Advanced Service, but for most use cases
// the built-in method SpreadsheetApp.getActiveSpreadsheet()
//     .getRange(range).setValues(values) is more appropriate.

// Change the spreadsheet's title.
var updateSpreadsheetPropertiesRequest = Sheets.newUpdateSpreadsheetPropertiesRequest();
updateSpreadsheetPropertiesRequest.properties = Sheets.newSpreadsheetProperties();
updateSpreadsheetPropertiesRequest.properties.title = title;
updateSpreadsheetPropertiesRequest.fields = 'title';

// Find and replace text.
var findReplaceRequest = Sheets.newFindReplaceRequest();
findReplaceRequest.find = find;
findReplaceRequest.replacement = replacement;
findReplaceRequest.allSheets = true;

var requests = [Sheets.newRequest(), Sheets.newRequest()];
requests[0].updateSpreadsheetProperties = updateSpreadsheetPropertiesRequest;
requests[1].findReplace = findReplaceRequest;

var batchUpdateRequest = Sheets.newBatchUpdateSpreadsheetRequest();
batchUpdateRequest.requests = requests;

// Add additional requests (operations)
var result = Sheets.Spreadsheets.batchUpdate(batchUpdateRequest, spreadsheetId);

Java

sheets/snippets/src/main/java/SpreadsheetSnippets.java
List<Request> requests = new ArrayList<>();
// Change the spreadsheet's title.
requests.add(new Request()
        .setUpdateSpreadsheetProperties(new UpdateSpreadsheetPropertiesRequest()
                .setProperties(new SpreadsheetProperties()
                        .setTitle(title))
                .setFields("title")));
// Find and replace text.
requests.add(new Request()
        .setFindReplace(new FindReplaceRequest()
                .setFind(find)
                .setReplacement(replacement)
                .setAllSheets(true)));
// Add additional requests (operations) ...

BatchUpdateSpreadsheetRequest body =
        new BatchUpdateSpreadsheetRequest().setRequests(requests);
BatchUpdateSpreadsheetResponse response =
        service.spreadsheets().batchUpdate(spreadsheetId, body).execute();
FindReplaceResponse findReplaceResponse = response.getReplies().get(1).getFindReplace();
System.out.printf("%d replacements made.", findReplaceResponse.getOccurrencesChanged());

JavaScript

sheets/snippets/snippets.js
var requests = [];
// Change the spreadsheet's title.
requests.push({
  updateSpreadsheetProperties: {
    properties: {
      title: title
    },
    fields: 'title'
  }
});
// Find and replace text.
requests.push({
  findReplace: {
    find: find,
    replacement: replacement,
    allSheets: true
  }
});
// Add additional requests (operations) ...

var batchUpdateRequest = {requests: requests}

gapi.client.sheets.spreadsheets.batchUpdate({
  spreadsheetId: spreadsheetId,
  resource: batchUpdateRequest
}).then((response) => {
  var findReplaceResponse = response.result.replies[1].findReplace;
  console.log(`${findReplaceResponse.occurrencesChanged} replacements made.`);
});

Node.js

sheets/snippets/snippets.js
let requests = [];
// Change the spreadsheet's title.
requests.push({
  updateSpreadsheetProperties: {
    properties: {
      title,
    },
    fields: 'title',
  },
});
// Find and replace text.
requests.push({
  findReplace: {
    find,
    replacement,
    allSheets: true,
  },
});
// Add additional requests (operations) ...
const batchUpdateRequest = {requests};
this.sheetsService.spreadsheets.batchUpdate({
  spreadsheetId,
  resource: batchUpdateRequest,
}, (err, response) => {
  if (err) {
    // Handle error
    console.log(err);
  } else {
    const findReplaceResponse = response.replies[1].findReplace;
    console.log(`${findReplaceResponse.occurrencesChanged} replacements made.`);
  }
});

PHP

sheets/snippets/src/SpreadsheetSnippets.php
<?php
$requests = [
  // Change the spreadsheet's title.
  new Google_Service_Sheets_Request([
      'updateSpreadsheetProperties' => [
          'properties' => [
              'title' => $title
          ],
          'fields' => 'title'
      ]
  ]),
  // Find and replace text.
  new Google_Service_Sheets_Request([
      'findReplace' => [
          'find' => $find,
          'replacement' => $replacement,
          'allSheets' => true
      ]
  ])
];

// Add additional requests (operations) ...
$batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest([
    'requests' => $requests
]);

$response = $service->spreadsheets->batchUpdate($spreadsheetId, $batchUpdateRequest);
$findReplaceResponse = $response->getReplies()[1]->getFindReplace();
printf("%s replacements made.\n",
$findReplaceResponse->getOccurrencesChanged());

Python

sheets/snippets/spreadsheet_snippets.py
requests = []
# Change the spreadsheet's title.
requests.append({
    'updateSpreadsheetProperties': {
        'properties': {
            'title': title
        },
        'fields': 'title'
    }
})
# Find and replace text
requests.append({
    'findReplace': {
        'find': find,
        'replacement': replacement,
        'allSheets': True
    }
})
# Add additional requests (operations) ...

body = {
    'requests': requests
}
response = service.spreadsheets().batchUpdate(
    spreadsheetId=spreadsheet_id,
    body=body).execute()
find_replace_response = response.get('replies')[1].get('findReplace')
print('{0} replacements made.'.format(
    find_replace_response.get('occurrencesChanged')))

Ruby

sheets/snippets/lib/spreadsheet_snippets.rb
requests = []
# Change the name of sheet ID '0' (the default first sheet on every
# spreadsheet)
requests.push({
                update_sheet_properties: {
                  properties: { sheet_id: 0, title: 'New Sheet Name' },
                  fields:     'title'
                }
              })
# Find and replace text
requests.push({
                find_replace: {
                  find:        find,
                  replacement: replacement,
                  all_sheets:  true
                }
              })
# Add additional requests (operations) ...

body = { requests: requests }
result = service.batch_update_spreadsheet(spreadsheet_id, body, {})
find_replace_response = result.replies[1].find_replace
puts "#{find_replace_response.occurrences_changed} replacements made."