forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			562 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			562 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								sidebar_position: 2
							 | 
						||
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Google Sheets
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import Tabs from '@theme/Tabs';
							 | 
						||
| 
								 | 
							
								import TabItem from '@theme/TabItem';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This demo uses [`node-google-spreadsheet`](https://theoephraim.github.io/node-google-spreadsheet)
							 | 
						||
| 
								 | 
							
								to interact with Google Sheets v4 API.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Code that does not directly relate to SheetJS APIs are tucked away.  Click on
							 | 
						||
| 
								 | 
							
								the "click to show" blocks to see the code snippets.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Initial Configuration
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Install the dependencies:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```bash
							 | 
						||
| 
								 | 
							
								npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz google-spreadsheet@3.3.0
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The library README has a [guide](https://theoephraim.github.io/node-google-spreadsheet/#/getting-started/authentication)
							 | 
						||
| 
								 | 
							
								for configuring a service worker with write access to the document.  Following
							 | 
						||
| 
								 | 
							
								the service worker guide, the JSON key should be saved to `key.json`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The following helper function attempts to authenticate and access the specified
							 | 
						||
| 
								 | 
							
								sheet by ID.  The code should be copied and saved to `common.js`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js title=common.js
							 | 
						||
| 
								 | 
							
								const fs = require("fs");
							 | 
						||
| 
								 | 
							
								const { GoogleSpreadsheet } = require('google-spreadsheet');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = async(ID) => {
							 | 
						||
| 
								 | 
							
								  /* get credentials */
							 | 
						||
| 
								 | 
							
								  const creds = JSON.parse(fs.readFileSync('key.json'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* initialize sheet and authenticate */
							 | 
						||
| 
								 | 
							
								  const doc = new GoogleSpreadsheet(ID);
							 | 
						||
| 
								 | 
							
								  await doc.useServiceAccountAuth(creds);
							 | 
						||
| 
								 | 
							
								  await doc.loadInfo();
							 | 
						||
| 
								 | 
							
								  return doc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Exporting Document Data to a File
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The goal is to create an XLSB export from a Google Sheet.  Google Sheets does
							 | 
						||
| 
								 | 
							
								not natively support the XLSB format.  SheetJS fills the gap.  [The last subsection](#how-to-run-export-example) includes detailed instructions for running locally.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Connecting to the Document
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This uses the `common.js` helper from above:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* Connect to Google Sheet */
							 | 
						||
| 
								 | 
							
								const ID = "<google sheet id>";
							 | 
						||
| 
								 | 
							
								const doc = await require("./common")(ID);
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Creating a New Workbook
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`XLSX.utils.book_new()` creates an empty workbook with no worksheets:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* create a blank workbook */
							 | 
						||
| 
								 | 
							
								const wb = XLSX.utils.book_new();
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Looping across the Document
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`doc.sheetsByIndex` is an array of worksheets in the Google Sheet Document.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* Loop across the Document sheets */
							 | 
						||
| 
								 | 
							
								for(let i = 0; i < doc.sheetsByIndex.length; ++i) {
							 | 
						||
| 
								 | 
							
								  const sheet = doc.sheetsByIndex[i];
							 | 
						||
| 
								 | 
							
								  /* Get the worksheet name */
							 | 
						||
| 
								 | 
							
								  const name = sheet.title;
							 | 
						||
| 
								 | 
							
								  /* ... */
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Convert a Google Sheets sheet to a SheetJS Worksheet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The idea is to extract the raw data from the Google Sheet headers and combine
							 | 
						||
| 
								 | 
							
								with the raw data rows to produce a large array of arrays.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								  /* get the header and data rows */
							 | 
						||
| 
								 | 
							
								  await sheet.loadHeaderRow();
							 | 
						||
| 
								 | 
							
								  const header = sheet.headerValues;
							 | 
						||
| 
								 | 
							
								  const rows = await sheet.getRows();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* construct the array of arrays */
							 | 
						||
| 
								 | 
							
								  const aoa = [header].concat(rows.map(r => r._rawData));
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This can be converted to a SheetJS worksheet using `XLSX.utils.aoa_to_sheet`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								  /* generate a SheetJS Worksheet */
							 | 
						||
| 
								 | 
							
								  const ws = XLSX.utils.aoa_to_sheet(aoa);
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`XLSX.utils.book_append_sheet` will add the worksheet to the workbook:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								  /* add to workbook */
							 | 
						||
| 
								 | 
							
								  XLSX.utils.book_append_sheet(wb, ws, name);
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Generating an XLSB file
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`XLSX.writeFile` will write a file in the filesystem:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* write to SheetJS.xlsb */
							 | 
						||
| 
								 | 
							
								XLSX.writeFile(wb, "SheetJS.xlsb");
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### How to Run Export Example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>How to run locally</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								0) Follow the [Authentication and Service Account](https://theoephraim.github.io/node-google-spreadsheet/#/getting-started/authentication)
							 | 
						||
| 
								 | 
							
								instructions.  At the end, you should have
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- Created a project and enabled the Sheets API
							 | 
						||
| 
								 | 
							
								- Created a service account with a JSON key
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Move the generated JSON key to `key.json` in your project folder.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1) Create a new Google Sheet and share with the generated service account.  It
							 | 
						||
| 
								 | 
							
								should be granted the "Editor" role
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								2) Install the dependencies:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz google-spreadsheet@3.3.0
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								2) Save the following snippet to `common.js`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js title=common.js
							 | 
						||
| 
								 | 
							
								const fs = require("fs");
							 | 
						||
| 
								 | 
							
								const { GoogleSpreadsheet } = require('google-spreadsheet');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = async(ID) => {
							 | 
						||
| 
								 | 
							
								  /* get credentials */
							 | 
						||
| 
								 | 
							
								  const creds = JSON.parse(fs.readFileSync('key.json'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* initialize sheet and authenticate */
							 | 
						||
| 
								 | 
							
								  const doc = new GoogleSpreadsheet(ID);
							 | 
						||
| 
								 | 
							
								  await doc.useServiceAccountAuth(creds);
							 | 
						||
| 
								 | 
							
								  await doc.loadInfo();
							 | 
						||
| 
								 | 
							
								  return doc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								3) Save the following snippet to `pull.js`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js title=pull.js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* create a blank workbook */
							 | 
						||
| 
								 | 
							
								const wb = XLSX.utils.book_new();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const init = require("./common");
							 | 
						||
| 
								 | 
							
								const ID = "<google sheet ID>";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(async() => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const doc = await init(ID);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for(let i = 0; i < doc.sheetsByIndex.length; ++i) {
							 | 
						||
| 
								 | 
							
								    const sheet = doc.sheetsByIndex[i];
							 | 
						||
| 
								 | 
							
								    const name = sheet.title;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* get the header and data rows */
							 | 
						||
| 
								 | 
							
								    await sheet.loadHeaderRow();
							 | 
						||
| 
								 | 
							
								    const header = sheet.headerValues;
							 | 
						||
| 
								 | 
							
								    const rows = await sheet.getRows();
							 | 
						||
| 
								 | 
							
								    const aoa = [header].concat(rows.map(r => r._rawData));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* generate a SheetJS Worksheet */
							 | 
						||
| 
								 | 
							
								    const ws = XLSX.utils.aoa_to_sheet(aoa);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* add to workbook */
							 | 
						||
| 
								 | 
							
								    XLSX.utils.book_append_sheet(wb, ws, name);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* write to SheetJS.xlsb */
							 | 
						||
| 
								 | 
							
								  XLSX.writeFile(wb, "SheetJS.xlsb");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								})();
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								4) Replace `<google sheet ID>` with the ID of the actual document.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								5) Run `node pull.js` once. It will create `SheetJS.xlsb`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								6) Open `SheetJS.xlsb` and confirm the contents are the same as Google Sheets.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								7) Change some cells in the Google Sheets Document.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								8) Run `node pull.js` again and reopen `SheetJS.xlsb` to confirm value changes.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Updating a Document from a Local File
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The goal is to refresh a Google Sheet based on a local file.  The problem can
							 | 
						||
| 
								 | 
							
								be broken down into a few steps.  [The last subsection](#how-to-run-update-example)
							 | 
						||
| 
								 | 
							
								includes detailed instructions for running locally.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Reading the Workbook File
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`XLSX.readFile` can read files from the filesystem.  The following line reads
							 | 
						||
| 
								 | 
							
								`sheetjs.xlsx` from the current directory:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								const wb = XLSX.readFile("sheetjs.xlsx");
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Connecting to the Document
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This uses the `common.js` helper from above:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* Connect to Google Sheet */
							 | 
						||
| 
								 | 
							
								const ID = "<google sheet id>";
							 | 
						||
| 
								 | 
							
								const doc = await require("./common")(ID);
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Clearing the Document
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Google Sheets does not allow users to delete every worksheet.  The snippet
							 | 
						||
| 
								 | 
							
								deletes every worksheet after the first, then clears the first worksheet.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* clear workbook */
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  /* delete all sheets after the first sheet */
							 | 
						||
| 
								 | 
							
								  const old_sheets = doc.sheetsByIndex;
							 | 
						||
| 
								 | 
							
								  for(let i = 1; i < old_sheets.length; ++i) {
							 | 
						||
| 
								 | 
							
								    await old_sheets[i].delete();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  /* clear first worksheet */
							 | 
						||
| 
								 | 
							
								  old_sheets[0].clear();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Update First Worksheet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In the SheetJS workbook object, worksheet names are stored in the `SheetNames`
							 | 
						||
| 
								 | 
							
								property.  The first worksheet name is `wb.SheetNames[0]`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const name = wb.SheetNames[0];
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `Sheets` property is an object whose keys are sheet names and whose values
							 | 
						||
| 
								 | 
							
								are worksheet objects.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const ws = wb.Sheets[name];
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In the Google Sheet, `doc.sheetsByIndex[0]` is a reference to the first sheet:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const sheet = doc.sheetsByIndex[0];
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### Update Sheet Name
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The worksheet name is assigned by using the `updateProperties` method.  The
							 | 
						||
| 
								 | 
							
								desired sheet name is the name of the first worksheet from the file.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* update worksheet name */
							 | 
						||
| 
								 | 
							
								await sheet.updateProperties({title: name});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### Update Worksheet Data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`sheet.addRows` reads an Array of Arrays of values. `XLSX.utils.sheet_to_json`
							 | 
						||
| 
								 | 
							
								can generate this exact shape with the option `header: 1`.  Unfortunately
							 | 
						||
| 
								 | 
							
								Google Sheets requires at least one "Header Row".  This can be implemented by
							 | 
						||
| 
								 | 
							
								converting the entire worksheet to an Array of Arrays and setting the header
							 | 
						||
| 
								 | 
							
								row to the first row of the result:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								/* generate array of arrays from the first worksheet */
							 | 
						||
| 
								 | 
							
								const aoa = XLSX.utils.sheet_to_json(ws, {header: 1});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* set document header row to first row of the AOA */
							 | 
						||
| 
								 | 
							
								await sheet.setHeaderRow(aoa[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* add the remaining rows */
							 | 
						||
| 
								 | 
							
								await sheet.addRows(aoa.slice(1));
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Add the Other Worksheets
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Each name in the SheetJS Workbook `SheetNames` array maps to a worksheet.  The
							 | 
						||
| 
								 | 
							
								loop over the remaining worksheet names looks like
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								for(let i = 1; i < wb.SheetNames.length; ++i) {
							 | 
						||
| 
								 | 
							
								  /* wb.SheetNames[i] is the sheet name */
							 | 
						||
| 
								 | 
							
								  const name = wb.SheetNames[i];
							 | 
						||
| 
								 | 
							
								  /* wb.Sheets[name] is the worksheet object */
							 | 
						||
| 
								 | 
							
								  const ws = wb.Sheets[name];
							 | 
						||
| 
								 | 
							
								  /* ... */
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### Appending a Worksheet to the Document
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`doc.addSheet` accepts a properties object that includes the worksheet name:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								  const sheet = await doc.addSheet({title: name});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This creates a new worksheet, sets the tab name, and returns a reference to the
							 | 
						||
| 
								 | 
							
								created worksheet.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#### Update Worksheet Data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This is identical to the first worksheet code:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								  /* generate array of arrays from the first worksheet */
							 | 
						||
| 
								 | 
							
								  const aoa = XLSX.utils.sheet_to_json(ws, {header: 1});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* set document header row to first row of the AOA */
							 | 
						||
| 
								 | 
							
								  await sheet.setHeaderRow(aoa[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* add the remaining rows */
							 | 
						||
| 
								 | 
							
								  await sheet.addRows(aoa.slice(1));
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### How to Run Update Example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>How to run locally</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								0) Follow the [Authentication and Service Account](https://theoephraim.github.io/node-google-spreadsheet/#/getting-started/authentication)
							 | 
						||
| 
								 | 
							
								instructions.  At the end, you should have
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- Created a project and enabled the Sheets API
							 | 
						||
| 
								 | 
							
								- Created a service account with a JSON key
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Move the generated JSON key to `key.json` in your project folder.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1) Create a new Google Sheet and share with the generated service account.  It
							 | 
						||
| 
								 | 
							
								should be granted the "Editor" role
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								2) Install the dependencies:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz google-spreadsheet@3.3.0
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								2) Save the following snippet to `common.js`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js title=common.js
							 | 
						||
| 
								 | 
							
								const fs = require("fs");
							 | 
						||
| 
								 | 
							
								const { GoogleSpreadsheet } = require('google-spreadsheet');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = async(ID) => {
							 | 
						||
| 
								 | 
							
								  /* get credentials */
							 | 
						||
| 
								 | 
							
								  const creds = JSON.parse(fs.readFileSync('key.json'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* initialize sheet and authenticate */
							 | 
						||
| 
								 | 
							
								  const doc = new GoogleSpreadsheet(ID);
							 | 
						||
| 
								 | 
							
								  await doc.useServiceAccountAuth(creds);
							 | 
						||
| 
								 | 
							
								  await doc.loadInfo();
							 | 
						||
| 
								 | 
							
								  return doc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								3) Save the following snippet to `push.js`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js title=push.js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								const fs = require("fs");
							 | 
						||
| 
								 | 
							
								/* create dummy worksheet if `sheetjs.xlsx` does not exist */
							 | 
						||
| 
								 | 
							
								if(!fs.existsSync("sheetjs.xlsx")) {
							 | 
						||
| 
								 | 
							
								  const wb = XLSX.utils.book_new();
							 | 
						||
| 
								 | 
							
								  const ws1 = XLSX.utils.aoa_to_sheet([["a","b","c"],[1,2,3]]); XLSX.utils.book_append_sheet(wb, ws1, "Sheet1");
							 | 
						||
| 
								 | 
							
								  const ws2 = XLSX.utils.aoa_to_sheet([["a","b","c"],[4,5,6]]); XLSX.utils.book_append_sheet(wb, ws2, "Sheet2");
							 | 
						||
| 
								 | 
							
								  XLSX.writeFile(wb, "sheetjs.xlsx");
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/* read and parse sheetjs.xlsx */
							 | 
						||
| 
								 | 
							
								const wb = XLSX.readFile("sheetjs.xlsx");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const init = require("./common");
							 | 
						||
| 
								 | 
							
								const ID = "<google sheet ID>";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(async() => {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const doc = await init(ID);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* clear workbook */
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    /* delete all sheets after the first sheet */
							 | 
						||
| 
								 | 
							
								    const old_sheets = doc.sheetsByIndex;
							 | 
						||
| 
								 | 
							
								    for(let i = 1; i < old_sheets.length; ++i) {
							 | 
						||
| 
								 | 
							
								      await old_sheets[i].delete();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* clear first worksheet */
							 | 
						||
| 
								 | 
							
								    old_sheets[0].clear();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* write worksheets */
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    const name = wb.SheetNames[0];
							 | 
						||
| 
								 | 
							
								    const ws = wb.Sheets[name];
							 | 
						||
| 
								 | 
							
								    /* first worksheet already exists */
							 | 
						||
| 
								 | 
							
								    const sheet = doc.sheetsByIndex[0];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* update worksheet name */
							 | 
						||
| 
								 | 
							
								    await sheet.updateProperties({title: name});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* generate array of arrays from the first worksheet */
							 | 
						||
| 
								 | 
							
								    const aoa = XLSX.utils.sheet_to_json(ws, {header: 1});
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* set document header row to first row of the AOA */
							 | 
						||
| 
								 | 
							
								    await sheet.setHeaderRow(aoa[0])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* add the remaining rows */
							 | 
						||
| 
								 | 
							
								    await sheet.addRows(aoa.slice(1));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* the other worksheets must be created manually */
							 | 
						||
| 
								 | 
							
								    for(let i = 1; i < wb.SheetNames.length; ++i) {
							 | 
						||
| 
								 | 
							
								      const name = wb.SheetNames[i];
							 | 
						||
| 
								 | 
							
								      const ws = wb.Sheets[name];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const sheet = await doc.addSheet({title: name});
							 | 
						||
| 
								 | 
							
								      const aoa = XLSX.utils.sheet_to_json(ws, {header: 1});
							 | 
						||
| 
								 | 
							
								      await sheet.setHeaderRow(aoa[0])
							 | 
						||
| 
								 | 
							
								      await sheet.addRows(aoa.slice(1));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								})();
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								4) Replace `<google sheet ID>` with the ID of the actual document.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								5) Run `node push.js` once. It will create `sheetjs.xlsx` and update the sheet.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								6) Edit `sheetjs.xlsx` with some new data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								7) Run `node push.js` again and watch the Google Sheet update!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Using the Raw File Exports
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`node-google-spreadsheet` can download the XLSX or ODS export of the document.
							 | 
						||
| 
								 | 
							
								The functions return NodeJS `Buffer` data that can be parsed using SheetJS.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Sample Code</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SheetJS can read data from XLSX files and ODS files.  This example prints the
							 | 
						||
| 
								 | 
							
								worksheet names and CSV exports of each sheet.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<Tabs>
							 | 
						||
| 
								 | 
							
								  <TabItem value="xlsx" label="XLSX">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Connect to Google Sheet */
							 | 
						||
| 
								 | 
							
								const ID = "<google sheet id>";
							 | 
						||
| 
								 | 
							
								const doc = await require("./common")(ID);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Get XLSX export */
							 | 
						||
| 
								 | 
							
								const buf = await doc.downloadAsXLSX();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Parse with SheetJS */
							 | 
						||
| 
								 | 
							
								const wb = XLSX.read(buf);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Loop over the worksheet names */
							 | 
						||
| 
								 | 
							
								wb.SheetNames.forEach(name => {
							 | 
						||
| 
								 | 
							
								  /* Print the name to the console */
							 | 
						||
| 
								 | 
							
								  console.log(name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Get the corresponding worksheet object */
							 | 
						||
| 
								 | 
							
								  const sheet = wb.Sheets[name];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Print a CSV export of the worksheet */
							 | 
						||
| 
								 | 
							
								  console.log(XLSX.utils.sheet_to_csv(sheet));
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  </TabItem>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  <TabItem value="ods" label="ODS">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Connect to Google Sheet */
							 | 
						||
| 
								 | 
							
								const ID = "<google sheet id>";
							 | 
						||
| 
								 | 
							
								const doc = await require("./common")(ID);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Get XLSX export */
							 | 
						||
| 
								 | 
							
								const buf = await doc.downloadAsODS();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Parse with SheetJS */
							 | 
						||
| 
								 | 
							
								const wb = XLSX.read(buf);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Loop over the worksheet names */
							 | 
						||
| 
								 | 
							
								wb.SheetNames.forEach(name => {
							 | 
						||
| 
								 | 
							
								  /* Print the name to the console */
							 | 
						||
| 
								 | 
							
								  console.log(name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Get the corresponding worksheet object */
							 | 
						||
| 
								 | 
							
								  const sheet = wb.Sheets[name];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Print a CSV export of the worksheet */
							 | 
						||
| 
								 | 
							
								  console.log(XLSX.utils.sheet_to_csv(sheet));
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  </TabItem>
							 | 
						||
| 
								 | 
							
								</Tabs>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 |