The Google Sheets API Advanced Service has a strange habit of switching between using Google Sheet names like 'Sheet1' and the sheet ID that you would see in the URL, like 482103711.
This can be problematic when working with complex processes in the Sheets API.
One of the first things I do when running a complex process is to make an initial call to the Sheets.Spreadsheets.get() method to generate an array of all of the sheet tabs by name and sheet ID. Yes, it is an additional call to the API but if we do it initially in conjunction with any other core requests from the spreadsheet then we only need to do it one time.
This approach is limited to appending a single row to the bottom of the selected sheet and the append will only occur after the last row in the entire sheet where there is text.
There are, of course, some other approaches to appending data and finding the last row. Here are some that I have covered:
As of the time of this tutorial, there are a number of documentation errors and bugs in the constructor classes in Google Apps Script for the append method for the Sheets API advanced service.
With the advanced service, you can append multiple rows of data to your sheet.
Insert Rows or Overwrite Existing Rows
We can decide if we want to insert new rows after the end of our existing data or overwrite the existing empty spaces. This is particularly handy when used in conjunction with the below.
Select a target range
Say you have a dataset that you want to update that has a bunch of summary data below it. With the append method, you can select the range of the data all the way down to just above your summary data and append to it.
Insert data as Raw Data or User Formatted
You can also choose to either display the data as raw data input as is, or allow Google Sheets to format the data as if you are manually inputting it into each cell.
An Example
We will use this example to illustrate how the method works in the remainder of the tutorial.
Here we have a sheet of appendix data (Get it).
The most recent data ends on line 24. We also have a set of summary data starting on line 44.
Our doctor usually sends batches of data about the appendix of each patient they see in a week. They will append that cumulative data to the sheet at the end of each week.
In our example, you can see that we have placed this method in a JavaScript Try…Catch statement to handle any returned errors gracefully (lines 20-31).
The ‘append’ method returns an object that looks like this:
Probably the most important bit of information that you will get back from this object is the updatedRanges property. Everything else you will be able to get before making the append request. This property will give you the range of the updated data in A1Notation. From this, you may want to apply formatting or data validation.
2d Array of Data to Append
The first parameter is a little counterintuitive in that you must first declare an object which contains the values property. This property contains the 2d array of values that will be appended.
In our example, we mix up our 2d array of data to illustrate how some of the parameters may affect the data presented in the sheet. (lines 3-8)
More on this later
Spreadsheet ID
Next, we insert the Google Sheet ID of our spreadsheet.
We set this in our ssID variable. Line 2
Range To append to
The third parameter is the range to append to. This one is a little weird too but after you understand it, you’ll see that it is super handy.
Providing this range allows the Sheets API to search for the first empty row after the last row of data only in the range that you select.
This means that it will ignore other columns not within its search range that may have an end position much further down the sheet.
It also means that you can set your append between two sets of data in the same column. I illustrate this in our example above where we have a set of data running from A4:D24 and then a set of summary data from A44:B50, but we will append only after the first set of data.
In our example, we set this range to Sheet1:A5:A45.
Payload Object
The payload object or as Google calls it, the parameters, contain an object of optional parameters that you can include in your project to alter the outcome of the append or return your data in a different way.
After some considerable tests, I found that many of the parameters do not affect how the data is displayed on the sheet. However, there are three of note.
valueInputOption (mandatory)
One mandatory parameter must be included in each append call:
valueInputOption: "USER_ENTERED" // USER_ENTERED or RAWline 12
Using the USER_ENTERED method will evaluate the 2d array and append it as if the user manually entered it into Google Sheet. So this 2d array:
1
2
3
4
5
6
constdata=[
[94925,17,"retrocecal","15/02/2025"],
[94300,7,"=B21","16/02/2025"],
[30397,8,"retrocecal","=TODAY()"],
[82188,"10","pelvic","20/02/2025"],
]
… will look like this:
Google Sheets API USER_ENTERED
Here you can see that the string number has been converted to an actual number in the sheet and all of the formulas have been executed.
Whereas, if we selected the RAW option then the data would look like this:
Google Sheets API RAW
Now, the data is represented almost exactly as we had it in the code. The only difference is that the numbers have been influenced by our Google Sheets format to display ‘cm’ after the number in column B when a number is found. Note that the number in B28 is in fact text because it was a string in the code.
Further, all formulas are escaped with a “'” to display them as text.
Finally, the dates are now strings and no Google Sheets Date Number Values. These too are escaped with a “'“.
insertDataOption (optional)
One of the cool things with this ‘append’ method is that you can choose to either overwrite existing empty cells or insert whole new rows.
The insertDataOption allows us to do this by selecting between either “OVERWRITE” or “INSERT_ROWS”.
“OVERWRITE” simply appends over the current rows so our result in the example would look like this:
Google Sheets API insertDataOption OVERWRITE
Notice that the new data is written over the empty spaces below the orange line at A25:D28.
Now, let’s run the script again with “INSERT_ROWS” this time noting where the orange line is and also where the summary down the bottom starts:
Google Sheets API insertDataOption INSERT_ROWS
You can see now that 4 rows have been inserted directly below the last row of data. This has pushed the orange line down 4 rows. The data is then inserted into these new rows.
You can also see now that the summary data down the bottom has also moved down 4 rows.
includeValuesInResponse
You can also opt-in to include the values that you just added to your sheet back into your response object. So it might look like this:
If you chose the “USER_ENTERED” valueInputOption then the returned results will be transformed as you can see in the sample above.
By default, this option is set to false.
Also, note that using this option will slow down your process because it needs to bring the appended array back in its response to you.
Conclusion
As you can see the Google Sheets API Append method is a much more versatile approach to appending data in a Google Sheet in Apps Script. Of course, the API is not limited to Apps Script, the API can be used in other programming languages too.
I would love to hear how you used this ‘append’ method in your own projects. It really gives inspiration and insight for others. Feel free to make a comment below.
I have a client project coming up shortly where I will be diving back into the Google Sheets API Advanced Service in Google Apps Script. As part of my refamiliarisation with the API, I was thinking about the minimum number of API calls it would take to efficiently create a Google Sheets line archiver based on a set of multi-column parameters.
Here’s the example and the starter sheet if you want to play along.
The Sample Data Google Sheet: The Space Ship Manufacturing Fleet Requests
Stardate 78183.10, it’s surprising spreadsheets have not been improved upon in the almost half millennia since their origin, but they are still everpresent while the inevitable decay of other software products is a little more than the dust of a bygone memory.
We’ve decided to create an archiving automation for our spaceship-building bids for our new space fleet. We want to remove any bids from the sheet that have been declined and are before “2025-04-30”, (Damn it! Timeline inconsistencies already!!!!).
Once, we find these rows to archive, we want to remove the selected rows and append them to our ‘Archive’ sheet.
This is a small JavaScript pseudo-class that I use to quickly convert HEX to RGB colour format and RGB back to HEX and also create an array of gradient colours between two colours.
This guide is just a convenient place for me to store this reference for future use. I hope you can get some use out of it too.
Methods
rgbToHex(r, g, b) – returns String – A hexadecimal colour.
hexToRgb(hex) – returns [Number, Number, Number] – A red, green and blue (RGB) array of numbers from 0-255
generateColorGradient(colorStart, colorEnd, steps) – returns [[Number, Number, Number], ...] – An array of RGB colours by a set step.
The Code – Colory Class in JavaScript
Colory
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
* A small JavaScript Color Class used to:
* 1. Convet RGB to HEX
* 2. Convert HEX to RGB
* 3. Generate a colour gradient between two colours.
Generates a colour gradient based on the start and end colours at a set number of steps. Start and end colours can be added as hexadecimal string values or RGB number values within an array.
{String|[Number, Number, Number]} colorStart – Start colour as Hexadecimal string or set of 3 RGB 3-digit number series.
{String|[Number, Number, Number]} colorEnd – Start colour as Hexadecimal string or set of 3 RGB 3-digit number series.
{Number} steps – total number of steps to break down into.
Returns
{[[Number, Number, Number], …]} – A 2d array of RGB number arrays at the set step length.
Conclusion
This is mostly used for solo projects, often in Google Apps Script. As such, I have not included any error handling. This also increased performance because the code has less work to do. The JS doc tooltips are enough for me here and you could deduce most errors from natural errors caused in JavaScript.
My recommendation is to only add the methods that you believe you are going to use and remove the rest. No need to bloat out your own project.
Having said that, let me know if there are some other methods you would like to see in the class and I will have a crack at adding them in.