diff --git a/docz/docs/03-demos/09-cloud/03-gsheet.md b/docz/docs/03-demos/09-cloud/03-gsheet.md index d6d6731..48afbb9 100644 --- a/docz/docs/03-demos/09-cloud/03-gsheet.md +++ b/docz/docs/03-demos/09-cloud/03-gsheet.md @@ -16,6 +16,14 @@ referenced API version will be available in the future. ::: +:::note + +This demo focuses on external data processing. For Google Apps Script custom +functions, [the "Google Sheets" extension demo](/docs/demos/extensions/gsheet) +covers Apps Script integration. + +::: + ## Initial Configuration Install the dependencies: diff --git a/docz/docs/03-demos/10-extensions/04-gsheet.md b/docz/docs/03-demos/10-extensions/04-gsheet.md new file mode 100644 index 0000000..cfaa69b --- /dev/null +++ b/docz/docs/03-demos/10-extensions/04-gsheet.md @@ -0,0 +1,198 @@ +--- +title: Google Sheets +pagination_prev: demos/cloud/index +pagination_next: demos/bigdata/index +--- + +:::note + +This demo focuses on Google Apps Script custom functions. For external data +processing, [the "Google Sheets" cloud data demo](/docs/demos/cloud/gsheet) +covers the API for NodeJS scripts + +::: + +The [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. + +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) + +:::note + +This demo was last tested on 2023 April 17. + +::: + +## Integration Details + +### Adding the script + +The `clasp` command line tool can be used to upload the standalone script: + +```bash +npx @google/clasp clone SCRIPT_ID +curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js +npx @google/clasp push +``` + +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 +const response = UrlFetchApp.fetch("https://sheetjs.com/pres.numbers"); +``` + +`HTTPResponse#getContent` returns the file data as an array of *signed* bytes: + +```js +const content = response.getContent(); +``` + +The `"array"` type for `XLSX.read` expects an array of *unsigned* bytes. +Fortunately, the content can be corrected with bitwise operations: + +```js +for(var i = 0; i < content.length; ++i) content[i] &= 0xFF; +const wb = XLSX.read(content, { type: "array" }); +``` + +### Returning data + +`XLSX.utils.sheet_to_json` with the option `header: 1` returns arrays of arrays +that play nice with Google Sheets: + +```js +const first_worksheet = wb.Sheets[wb.SheetNames[0]]; +const aoa = XLSX.utils.sheet_to_json(first_worksheet, {header: 1}); +``` + +## 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 +``` + +A browser window should direct to an account selection page. Select the account +from the previous step. In the next page, there will be a title like + +> clasp – The Apps Script CLI wants to access your Google Account + +At the bottom of the screen, click "Allow". + +The terminal window should now state + +``` +Authorization successful. +``` + +### Creating a Sheet + +2) Sign into Google Sheets with the same account and create a new blank sheet + +3) Open up the apps script window (Extensions > Apps Script) + +4) Click the gear icon (Project Settings) and copy the Script ID + +### Cloning the Apps Script + +5) In the terminal window, create a new folder for your project: + +```bash +mkdir SheetJSGAS +cd SheetJSGAS +``` + +6) Clone the Apps Script project. The official command is: + +```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 + +7) Download the standalone build and move to the project directory: + +```bash +curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js +``` + +8) Push the project to Apps Script: + +```bash +npx @google/clasp push +``` + +:::caution + +If the push command fails with an error message like + +> User has not enabled the Apps Script API + +The message includes a URL (`https://script.google.com/home/usersettings` when +the demo was last tested). Visit that URL and enable the Google Apps Script API. +After enabling the API, run `npx @google/clasp push` again. + +::: + +9) Reopen the Google Sheet and Apps Script editor (Extensions > Apps Script). + +In the Files listing, there should be a new entry `xlsx.full.min.gs` + +### Creating a Custom Function + +10) In Apps Script editor, select `Code.gs` and erase the code in the editor. +Replace with the following function: + +```js title="Code.gs" +function SHEETJS(url) { + /* fetch data */ + const res = UrlFetchApp.fetch(url || "https://sheetjs.com/pres.numbers"); + 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; +} +``` + +Click the "Save Project" icon to save the project. + +11) In the Google Sheets window, select cell A1 and enter the formula + +``` +=SHEETJS("https://sheetjs.com/pres.numbers") +``` + +The file will be fetched and the contents will be written to the sheet. diff --git a/docz/static/gsheet/udf.png b/docz/static/gsheet/udf.png new file mode 100644 index 0000000..d7149ef Binary files /dev/null and b/docz/static/gsheet/udf.png differ diff --git a/docz/version.js b/docz/version.js index 592db19..64be04b 100644 --- a/docz/version.js +++ b/docz/version.js @@ -1,2 +1,2 @@ -const current = "0.19.2"; +const current = "0.19.3"; export default current;