2023-04-18 04:46:43 +00:00
|
|
|
|
---
|
2024-05-28 05:20:05 +00:00
|
|
|
|
title: Google Sheets Script Automation
|
|
|
|
|
sidebar_label: Google Sheets
|
2023-04-18 04:46:43 +00:00
|
|
|
|
pagination_prev: demos/cloud/index
|
|
|
|
|
pagination_next: demos/bigdata/index
|
2024-05-04 16:15:00 +00:00
|
|
|
|
sidebar_custom_props:
|
|
|
|
|
summary: Enhance data import functionality from Google Sheets
|
2023-04-18 04:46:43 +00:00
|
|
|
|
---
|
|
|
|
|
|
2023-04-27 09:12:19 +00:00
|
|
|
|
import current from '/version.js';
|
|
|
|
|
import CodeBlock from '@theme/CodeBlock';
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
:::info pass
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
This demo focuses on Google Apps Script custom functions.
|
|
|
|
|
|
|
|
|
|
[The "Google Sheets" cloud data demo](/docs/demos/cloud/gsheet) covers NodeJS
|
|
|
|
|
APIs for external data processing.
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
[Google Sheets](https://google.com/sheets/about/) is a collaborative spreadsheet
|
|
|
|
|
service with powerful JavaScript automation and user-defined functions.
|
|
|
|
|
|
|
|
|
|
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
|
|
|
|
data from spreadsheets.
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
Google Sheets currently does not provide support for working with Apple Numbers
|
|
|
|
|
files and some legacy file formats. SheetJS fills the gap.
|
|
|
|
|
|
|
|
|
|
The [Complete Demo](#complete-demo) defines a `SHEETJS` function that fetches a
|
|
|
|
|
remote file, parses the contents, and writes data to the sheet:
|
|
|
|
|
|
|
|
|
|
![Screenshot of final result](pathname:///gsheet/udf.png)
|
|
|
|
|
|
2024-03-12 06:47:52 +00:00
|
|
|
|
:::note Tested Deployments
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
This demo was tested in the following deployments:
|
|
|
|
|
|
|
|
|
|
| Clasp | Date |
|
|
|
|
|
|:--------|:-----------|
|
|
|
|
|
| `2.4.2` | 2024-12-31 |
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
## Integration Details
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
|
|
|
|
|
can be uploaded into an Apps Script project. Once uploaded, the `XLSX` variable
|
|
|
|
|
is available to other scripts in the project.
|
|
|
|
|
|
2023-04-18 04:46:43 +00:00
|
|
|
|
### Adding the script
|
|
|
|
|
|
|
|
|
|
The `clasp` command line tool can be used to upload the standalone script:
|
|
|
|
|
|
2023-04-27 09:12:19 +00:00
|
|
|
|
<CodeBlock language="bash">{`\
|
2023-04-18 04:46:43 +00:00
|
|
|
|
npx @google/clasp clone SCRIPT_ID
|
2023-04-27 09:12:19 +00:00
|
|
|
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
|
|
|
|
npx @google/clasp push`}
|
|
|
|
|
</CodeBlock>
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
Once uploaded, the script `xlsx.full.min.gs` will be added to the project.
|
|
|
|
|
|
|
|
|
|
The [Complete Demo](#complete-demo) includes more detailed setup instructions.
|
|
|
|
|
|
|
|
|
|
### Fetching data
|
|
|
|
|
|
|
|
|
|
`UrlFetchApp.fetch` performs a network request and returns a `HTTPResponse`:
|
|
|
|
|
|
|
|
|
|
```js
|
2024-04-26 04:16:13 +00:00
|
|
|
|
const response = UrlFetchApp.fetch("https://docs.sheetjs.com/pres.numbers");
|
2023-04-18 04:46:43 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`HTTPResponse#getContent` returns the file data as an array of *signed* bytes:
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
const content = response.getContent();
|
|
|
|
|
```
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
The SheetJS `read` method[^1] can read arrays of *unsigned* bytes. Fortunately,
|
|
|
|
|
the values in the array can be corrected with bitwise operations:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
for(var i = 0; i < content.length; ++i) content[i] &= 0xFF;
|
2025-01-06 02:51:20 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
After converting each signed byte to unsigned byte, the array can be parsed with
|
|
|
|
|
the `read` method:
|
|
|
|
|
|
|
|
|
|
```js
|
2023-04-18 04:46:43 +00:00
|
|
|
|
const wb = XLSX.read(content, { type: "array" });
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Returning data
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
The SheetJS `sheet_to_json` method[^2] with the option `header: 1` returns
|
|
|
|
|
arrays of arrays of data[^3]:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
const first_worksheet = wb.Sheets[wb.SheetNames[0]];
|
|
|
|
|
const aoa = XLSX.utils.sheet_to_json(first_worksheet, {header: 1});
|
|
|
|
|
```
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
Google Sheets will spread arrays of arrays across rows and columns. The `AOA`
|
|
|
|
|
function below returns an array that contains two arrays. The screenshot shows
|
|
|
|
|
the result of setting cell `A1` to the formula `=AOA()`:
|
|
|
|
|
|
|
|
|
|
<table>
|
|
|
|
|
<thead><tr><th>Custom Function</th><th>Google Sheets</th></tr></thead>
|
|
|
|
|
<tbody><tr><td>
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
function AOA(url) {
|
|
|
|
|
return [
|
|
|
|
|
["Sheet", "JS"],
|
|
|
|
|
[ 72, 62]
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
</td><td>
|
|
|
|
|
|
|
|
|
|
![Google Sheets result for AOA function](pathname:///gsheet/aoa-udf.png)
|
|
|
|
|
|
|
|
|
|
</td></tr></tbody>
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
2023-04-18 04:46:43 +00:00
|
|
|
|
## Complete Demo
|
|
|
|
|
|
|
|
|
|
This demo creates a function `SHEETJS(url)` that fetches the specified URL,
|
|
|
|
|
extracts data from the first worksheet, and writes the data
|
|
|
|
|
|
|
|
|
|
### Initial Setup
|
|
|
|
|
|
|
|
|
|
0) Sign into a Google account (or create a new one)
|
|
|
|
|
|
|
|
|
|
1) In a terminal window, run
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npx @google/clasp login
|
|
|
|
|
```
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
A browser window should direct to an account selection page.
|
|
|
|
|
|
|
|
|
|
2) Select the account from step 0.
|
|
|
|
|
|
|
|
|
|
The next page will include the following title:
|
|
|
|
|
|
|
|
|
|
> Sign in to clasp – The Apps Script CLI
|
|
|
|
|
|
|
|
|
|
![clasp sign-in](pathname:///gsheet/clasp-signin.png)
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
3) At the bottom of the screen, click "Continue".
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
4) In the next screen, check every box that mentions "Google Apps Script". When
|
|
|
|
|
the demo was last tested, the following were required:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
- Create and update Google Apps Script deployments.
|
|
|
|
|
- Create and update Google Apps Script projects.
|
|
|
|
|
|
|
|
|
|
![clasp permissions](pathname:///gsheet/clasp-perms.png)
|
|
|
|
|
|
|
|
|
|
5) Scroll to the bottom of the screen and click "Continue".
|
|
|
|
|
|
|
|
|
|
The browser will show the following message:
|
|
|
|
|
|
|
|
|
|
> Logged in! You may close this page.
|
|
|
|
|
|
|
|
|
|
The terminal window will show the following message:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
Authorization successful.
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Creating a Sheet
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
6) Sign into Google Sheets with the same account.
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
7) Create a new Blank spreadsheet.
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
8) Open the apps script window (Extensions > Apps Script)
|
|
|
|
|
|
|
|
|
|
![extensions - apps script](pathname:///gsheet/apps-script.png)
|
|
|
|
|
|
|
|
|
|
9) Click the gear icon (Project Settings) and copy the Script ID
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
### Cloning the Apps Script
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
10) In the terminal window, create a new folder for your project:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
mkdir SheetJSGAS
|
|
|
|
|
cd SheetJSGAS
|
|
|
|
|
```
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
11) Clone the Apps Script project. The official command is:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npx @google/clasp clone PASTE_YOUR_ID_HERE
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Type `npx @google/clasp clone ` in the terminal with a trailing space (do not
|
|
|
|
|
press Enter yet!), then copy the Script ID from the Apps Script settings page
|
|
|
|
|
and paste in the terminal. Press Enter after pasting the ID.
|
|
|
|
|
|
|
|
|
|
### Adding the SheetJS Library
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
12) Download the SheetJS Standalone script and move to the project directory:
|
2023-09-22 06:32:55 +00:00
|
|
|
|
|
|
|
|
|
<ul>
|
|
|
|
|
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
|
|
|
|
|
</ul>
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2023-05-07 13:58:36 +00:00
|
|
|
|
<CodeBlock language="bash">{`\
|
2023-04-27 09:12:19 +00:00
|
|
|
|
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
|
2023-05-07 13:58:36 +00:00
|
|
|
|
</CodeBlock>
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
13) Push the project to Apps Script:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npx @google/clasp push
|
|
|
|
|
```
|
|
|
|
|
|
2023-09-18 06:44:33 +00:00
|
|
|
|
:::caution pass
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2023-09-17 04:57:06 +00:00
|
|
|
|
If the Google Apps Script API is not enabled, the command will display an object
|
|
|
|
|
with `code: 403` and an error message about the Apps Script API:
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2023-09-17 04:57:06 +00:00
|
|
|
|
```js
|
|
|
|
|
{ // ...
|
|
|
|
|
code: 403,
|
|
|
|
|
errors: [
|
|
|
|
|
{
|
|
|
|
|
message: 'User has not enabled the Apps Script API. Enable it by ...',
|
|
|
|
|
domain: 'global',
|
|
|
|
|
reason: 'forbidden'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
```
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
The message includes a URL (`https://script.google.com/home/usersettings` when
|
2023-09-17 04:57:06 +00:00
|
|
|
|
the demo was last tested). Visit that URL.
|
|
|
|
|
|
|
|
|
|
If the Google Apps Script API is "Off", click on "Google Apps Script API" and
|
|
|
|
|
click on the slider to enable the API.
|
|
|
|
|
|
2023-04-18 04:46:43 +00:00
|
|
|
|
After enabling the API, run `npx @google/clasp push` again.
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
14) Reopen the Google Sheet and Apps Script editor (Extensions > Apps Script).
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
In the Files listing, there should be a new entry `xlsx.full.min.gs`
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
![xlsx.full.min.gs in Apps Script](pathname:///gsheet/xlsx-full-min-gs.png)
|
|
|
|
|
|
2023-04-18 04:46:43 +00:00
|
|
|
|
### Creating a Custom Function
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
15) In Apps Script editor, select `Code.gs` and erase the code in the editor.
|
2023-04-18 04:46:43 +00:00
|
|
|
|
Replace with the following function:
|
|
|
|
|
|
|
|
|
|
```js title="Code.gs"
|
|
|
|
|
function SHEETJS(url) {
|
|
|
|
|
/* fetch data */
|
2024-04-26 04:16:13 +00:00
|
|
|
|
const res = UrlFetchApp.fetch(url || "https://docs.sheetjs.com/pres.numbers");
|
2023-04-18 04:46:43 +00:00
|
|
|
|
const content = res.getContent();
|
|
|
|
|
|
|
|
|
|
/* fix data */
|
|
|
|
|
for(var i = 0; i < content.length; ++i) content[i] &= 0xFF;
|
|
|
|
|
|
|
|
|
|
/* parse */
|
|
|
|
|
const wb = XLSX.read(content, {type: "array"});
|
|
|
|
|
|
|
|
|
|
/* generate array of arrays from worksheet */
|
|
|
|
|
const ws = wb.Sheets[wb.SheetNames[0]];
|
|
|
|
|
const aoa = XLSX.utils.sheet_to_json(ws, {header: 1});
|
|
|
|
|
return aoa;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
Click the "Save project to Drive" icon (💾) to save the project.
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
2025-01-06 02:51:20 +00:00
|
|
|
|
16) In the Google Sheets window, select cell A1 and enter the formula
|
2023-04-18 04:46:43 +00:00
|
|
|
|
|
|
|
|
|
```
|
2024-04-26 04:16:13 +00:00
|
|
|
|
=SHEETJS("https://docs.sheetjs.com/pres.numbers")
|
2023-04-18 04:46:43 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The file will be fetched and the contents will be written to the sheet.
|
2025-01-06 02:51:20 +00:00
|
|
|
|
|
|
|
|
|
[^1]: See ["Input Type" in "Reading Files"](/docs/api/parse-options#input-type) for more details.
|
|
|
|
|
[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
|
|
|
|
[^3]: See ["Array of Arrays" in "Utilities"](/docs/api/utilities/array#array-of-arrays) for more details.
|