From 4770277d0b9dd0b53450f04c3c4613e0a9d607da Mon Sep 17 00:00:00 2001 From: SheetJS Date: Thu, 30 Nov 2023 02:10:37 -0500 Subject: [PATCH] dbox --- .../01-installation/02-frameworks.md | 2 +- .../01-installation/03-nodejs.md | 2 +- .../{08-local => 27-local}/01-file.md | 2 +- .../01-websql.md => 27-local/02-websql.md} | 4 +- .../{08-local => 27-local}/03-storageapi.md | 4 +- .../{08-local => 27-local}/05-clipboard.md | 4 +- .../{08-local => 27-local}/09-indexeddb.md | 9 +- .../{08-local => 27-local}/_category_.json | 2 +- .../03-demos/{08-local => 27-local}/index.md | 0 .../{09-cloud => 30-cloud}/01-salesforce.md | 45 +++-- .../{09-cloud => 30-cloud}/02-netsuite.md | 6 +- .../03-demos/{09-cloud => 30-cloud}/11-aws.md | 6 +- .../{09-cloud => 30-cloud}/12-azure.md | 37 +++- .../{09-cloud => 30-cloud}/18-github.md | 31 ++-- .../{09-cloud => 30-cloud}/19-deno.md | 6 +- .../{09-cloud => 30-cloud}/21-gsheet.md | 11 +- .../{09-cloud => 30-cloud}/22-airtable.md | 166 +++++++++++++++--- .../{09-cloud => 30-cloud}/31-dropbox.mdx | 8 +- .../{09-cloud => 30-cloud}/_category_.json | 2 +- .../03-demos/{09-cloud => 30-cloud}/index.md | 0 20 files changed, 247 insertions(+), 100 deletions(-) rename docz/docs/03-demos/{08-local => 27-local}/01-file.md (99%) rename docz/docs/03-demos/{08-local/01-websql.md => 27-local/02-websql.md} (99%) rename docz/docs/03-demos/{08-local => 27-local}/03-storageapi.md (99%) rename docz/docs/03-demos/{08-local => 27-local}/05-clipboard.md (96%) rename docz/docs/03-demos/{08-local => 27-local}/09-indexeddb.md (97%) rename docz/docs/03-demos/{08-local => 27-local}/_category_.json (60%) rename docz/docs/03-demos/{08-local => 27-local}/index.md (100%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/01-salesforce.md (93%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/02-netsuite.md (97%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/11-aws.md (99%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/12-azure.md (94%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/18-github.md (89%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/19-deno.md (95%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/21-gsheet.md (95%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/22-airtable.md (57%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/31-dropbox.mdx (97%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/_category_.json (64%) rename docz/docs/03-demos/{09-cloud => 30-cloud}/index.md (100%) diff --git a/docz/docs/02-getting-started/01-installation/02-frameworks.md b/docz/docs/02-getting-started/01-installation/02-frameworks.md index e2d33ea..38e2ab7 100644 --- a/docz/docs/02-getting-started/01-installation/02-frameworks.md +++ b/docz/docs/02-getting-started/01-installation/02-frameworks.md @@ -65,7 +65,7 @@ Snyk security tooling may report errors involving "Prototype Pollution": Prototype Pollution [Medium Severity][https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926] ``` -As noted in the [Snyk report](https://web.archive.org/web/20230920204324/https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926): +As noted in the [Snyk report](https://web.archive.org/web/20231129100639/https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926): > The issue is resolved in version 0.19.3 diff --git a/docz/docs/02-getting-started/01-installation/03-nodejs.md b/docz/docs/02-getting-started/01-installation/03-nodejs.md index d1dfd8f..3f02b35 100644 --- a/docz/docs/02-getting-started/01-installation/03-nodejs.md +++ b/docz/docs/02-getting-started/01-installation/03-nodejs.md @@ -55,7 +55,7 @@ Snyk security tooling may report errors involving "Prototype Pollution": Prototype Pollution [Medium Severity][https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926] ``` -As noted in the [Snyk report](https://web.archive.org/web/20230920204324/https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926): +As noted in the [Snyk report](https://web.archive.org/web/20231129100639/https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926): > The issue is resolved in version 0.19.3 diff --git a/docz/docs/03-demos/08-local/01-file.md b/docz/docs/03-demos/27-local/01-file.md similarity index 99% rename from docz/docs/03-demos/08-local/01-file.md rename to docz/docs/03-demos/27-local/01-file.md index 723bab7..6d04a9f 100644 --- a/docz/docs/03-demos/08-local/01-file.md +++ b/docz/docs/03-demos/27-local/01-file.md @@ -446,7 +446,7 @@ This browser demo was tested in the following environments: | Browser | Date | |:------------|:-----------| -| Chrome 119 | 2023-11-04 | +| Chrome 119 | 2023-11-30 | Some lesser-used browsers do not support File System Access API: diff --git a/docz/docs/03-demos/08-local/01-websql.md b/docz/docs/03-demos/27-local/02-websql.md similarity index 99% rename from docz/docs/03-demos/08-local/01-websql.md rename to docz/docs/03-demos/27-local/02-websql.md index 97af103..5212e69 100644 --- a/docz/docs/03-demos/08-local/01-websql.md +++ b/docz/docs/03-demos/27-local/02-websql.md @@ -144,13 +144,13 @@ This workbook is typically exported to the filesystem with `writeFile`[^6]. ## Live Demo -:::note +:::note Tested Deployments This browser demo was tested in the following environments: | Browser | Date | |:------------|:-----------| -| Chrome 117 | 2023-10-13 | +| Chrome 119 | 2023-11-30 | Some lesser-used browsers do not support WebSQL: diff --git a/docz/docs/03-demos/08-local/03-storageapi.md b/docz/docs/03-demos/27-local/03-storageapi.md similarity index 99% rename from docz/docs/03-demos/08-local/03-storageapi.md rename to docz/docs/03-demos/27-local/03-storageapi.md index fb5635b..81cdf1c 100644 --- a/docz/docs/03-demos/08-local/03-storageapi.md +++ b/docz/docs/03-demos/27-local/03-storageapi.md @@ -14,13 +14,13 @@ This demo covers two common use patterns: - "Row Objects" shows a simple convention for loading and storing row objects - "Simple Strings" discusses how to persist and recover a raw Storage -:::note +:::note Tested Deployments Each browser demo was tested in the following environments: | Browser | Date | |:------------|:-----------| -| Chrome 116 | 2023-09-17 | +| Chrome 119 | 2023-11-30 | | Safari 16.6 | 2023-09-17 | ::: diff --git a/docz/docs/03-demos/08-local/05-clipboard.md b/docz/docs/03-demos/27-local/05-clipboard.md similarity index 96% rename from docz/docs/03-demos/08-local/05-clipboard.md rename to docz/docs/03-demos/27-local/05-clipboard.md index 807048b..7b2a0a0 100644 --- a/docz/docs/03-demos/08-local/05-clipboard.md +++ b/docz/docs/03-demos/27-local/05-clipboard.md @@ -16,13 +16,13 @@ XLS (both '97-2004 and '95), and SpreadsheetML 2003. Not all Clipboard APIs offer access to all clipboard types. -:::note +:::note Tested Deployments Each browser demo was tested in the following environments: | Browser | Date | |:------------|:-----------| -| Chrome 116 | 2023-09-01 | +| Chrome 119 | 2023-11-30 | | Safari 16.6 | 2023-09-01 | | Brave 1.57 | 2023-09-01 | diff --git a/docz/docs/03-demos/08-local/09-indexeddb.md b/docz/docs/03-demos/27-local/09-indexeddb.md similarity index 97% rename from docz/docs/03-demos/08-local/09-indexeddb.md rename to docz/docs/03-demos/27-local/09-indexeddb.md index 633a019..d08bc1f 100644 --- a/docz/docs/03-demos/08-local/09-indexeddb.md +++ b/docz/docs/03-demos/27-local/09-indexeddb.md @@ -37,13 +37,14 @@ production sites. ### localForage -:::note +:::note Tested Deployments This demo was last tested in the following environments: | Browser | Date | `localForage` | |:------------|:-----------|:--------------| -| Chrome 117 | 2023-10-18 | 1.10.0 | +| Chrome 119 | 2023-11-30 | 1.10.0 | +| Safari 17.0 | 2023-11-30 | 1.10.0 | ::: @@ -108,13 +109,13 @@ function SheetJSLocalForage() { ### DexieJS -:::note +:::note Tested Deployments This demo was last tested in the following environments: | Browser | Date | DexieJS | |:------------|:-----------|:--------| -| Chrome 117 | 2023-10-18 | 3.2.4 | +| Chrome 119 | 2023-11-30 | 3.2.4 | ::: diff --git a/docz/docs/03-demos/08-local/_category_.json b/docz/docs/03-demos/27-local/_category_.json similarity index 60% rename from docz/docs/03-demos/08-local/_category_.json rename to docz/docs/03-demos/27-local/_category_.json index 3e07617..8516511 100644 --- a/docz/docs/03-demos/08-local/_category_.json +++ b/docz/docs/03-demos/27-local/_category_.json @@ -1,4 +1,4 @@ { "label": "Local Data", - "position": 8 + "position": 27 } \ No newline at end of file diff --git a/docz/docs/03-demos/08-local/index.md b/docz/docs/03-demos/27-local/index.md similarity index 100% rename from docz/docs/03-demos/08-local/index.md rename to docz/docs/03-demos/27-local/index.md diff --git a/docz/docs/03-demos/09-cloud/01-salesforce.md b/docz/docs/03-demos/30-cloud/01-salesforce.md similarity index 93% rename from docz/docs/03-demos/09-cloud/01-salesforce.md rename to docz/docs/03-demos/30-cloud/01-salesforce.md index c95b5cd..6f7e751 100644 --- a/docz/docs/03-demos/09-cloud/01-salesforce.md +++ b/docz/docs/03-demos/30-cloud/01-salesforce.md @@ -27,7 +27,7 @@ may require some adjustments. The official documentation should be consulted. ::: -:::note +:::note Tested Deployments This demo was last tested on 2023 September 30 using Lightning API version `58.0`. @@ -71,6 +71,7 @@ It is recommended to load the library in a callback. For example, the following ```js import { LightningElement, api } from 'lwc'; import { loadScript } from 'lightning/platformResourceLoader'; +// highlight-next-line import sheetjs from '@salesforce/resourceUrl/sheetjs'; export default class SheetComponent extends LightningElement { @@ -96,21 +97,17 @@ export default class SheetComponent extends LightningElement { ### Exporting Data from SF List -:::note pass - -There are many different data types and APIs. This demo uses the deprecated -`getListUi` function to pull account data. - -::: - -Using the LWC Wire Service, components receive data in separate events. Exports -are typically generated in a separate event handler. Component state is normally -used to handle the timing mismatch. +Using the LWC Wire Service, components receive data in separate events.[^3] +Event handlers typically store the updated data in component state, ensuring the +data is available when a spreadsheet export is requested. #### Getting Account Data -The main method to obtain data is `getListUi` and the key for account data is -`ACCOUNT_OBJECT`: +This demo uses the deprecated `getListUi` function[^4] to pull account data. +`getListUi` requires the name of the LWC object (`objectApiName` property) and +name of the LWC list view (`listViewApiName` property) + +The following snippet receives data from the "All Accounts" list view: ```js import { LightningElement, wire } from 'lwc'; @@ -231,10 +228,10 @@ export default class SheetComponent extends LightningElement { #### Exporting Data This is readily exported to a spreadsheet in a callback function. Starting from -the array of arrays, the SheetJS `aoa_to_sheet` method[^3] generates a SheetJS -sheet object[^4]. A workbook object[^5] is created with `book_new`[^6] and the -sheet is added with `book_append_sheet`[^7]. Finally, the SheetJS `writeFile` -method creates a XLSX file and initiates a download[^8]. +the array of arrays, the SheetJS `aoa_to_sheet` method[^5] generates a SheetJS +sheet object[^6]. A workbook object[^7] is created with `book_new`[^8] and the +sheet is added with `book_append_sheet`[^9]. Finally, the SheetJS `writeFile` +method creates a XLSX file and initiates a download[^10]. ```js @api async download() { @@ -708,9 +705,11 @@ cell styling, automatic column width calculations, and frozen rows. [^1]: It is strongly recommended to review the [detailed introduction in the Salesforce documentation](https://developer.salesforce.com/docs/platform/lwc/guide/get-started-introduction.html) [^2]: The `XLSX` variable is the main global for the SheetJS library. It exposes methods as described in ["API Reference"](/docs/api/) -[^3]: See [`aoa_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-arrays-input) -[^4]: See ["Sheet Objects"](/docs/csf/sheet) -[^5]: See ["Workbook Object"](/docs/csf/book) -[^6]: See [`book_new` in "Utilities"](/docs/api/utilities/wb) -[^7]: See [`book_append_sheet` in "Utilities"](/docs/api/utilities/wb) -[^8]: See [`writeFile` in "Writing Files"](/docs/api/write-options) \ No newline at end of file +[^3]: See ["Understand the Wire Service"](https://developer.salesforce.com/docs/platform/lwc/guide/data-wire-service-about.html) in the Salesforce LWC documentation. +[^4]: See [`getListUI`](https://developer.salesforce.com/docs/platform/lwc/guide/reference-get-list-ui.html) in the Salesforce LWC documentation. +[^5]: See [`aoa_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-arrays-input) +[^6]: See ["Sheet Objects"](/docs/csf/sheet) +[^7]: See ["Workbook Object"](/docs/csf/book) +[^8]: See [`book_new` in "Utilities"](/docs/api/utilities/wb) +[^9]: See [`book_append_sheet` in "Utilities"](/docs/api/utilities/wb) +[^10]: See [`writeFile` in "Writing Files"](/docs/api/write-options) \ No newline at end of file diff --git a/docz/docs/03-demos/09-cloud/02-netsuite.md b/docz/docs/03-demos/30-cloud/02-netsuite.md similarity index 97% rename from docz/docs/03-demos/09-cloud/02-netsuite.md rename to docz/docs/03-demos/30-cloud/02-netsuite.md index dd0d10c..249fabc 100644 --- a/docz/docs/03-demos/09-cloud/02-netsuite.md +++ b/docz/docs/03-demos/30-cloud/02-netsuite.md @@ -18,7 +18,7 @@ data from spreadsheets. This demo explores the SuiteScript scripting features in NetSuite. We'll explore how to use SheetJS in SuiteScripts for reading and writing files in NetSuite. -:::note +:::note Tested Deployments This demo was verified by NetSuite consultants in the following deployments: @@ -40,8 +40,8 @@ to the file cabinet and referenced in the `define` call in SuiteScripts. :::info pass -SheetJS scripts have been tested against the Rhino engine[^3] and work in both -SuiteScript 2.0 and SuiteScript 2.1. +SheetJS scripts have been tested against the Rhino JavaScript engine[^3] and +work in both SuiteScript 2.0 and SuiteScript 2.1 deployments. ::: diff --git a/docz/docs/03-demos/09-cloud/11-aws.md b/docz/docs/03-demos/30-cloud/11-aws.md similarity index 99% rename from docz/docs/03-demos/09-cloud/11-aws.md rename to docz/docs/03-demos/30-cloud/11-aws.md index bf39824..01f602a 100644 --- a/docz/docs/03-demos/09-cloud/11-aws.md +++ b/docz/docs/03-demos/30-cloud/11-aws.md @@ -7,7 +7,7 @@ pagination_next: demos/extensions/index import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; -[Amazon Web Services](https://aws.amazon.com/) (AWS) is a Cloud Services +[Amazon Web Services](https://aws.amazon.com/) (AWS) is a cloud services platform which includes traditional virtual machine support, "Serverless Functions" and cloud storage. @@ -31,7 +31,7 @@ will be available in the future. ::: -:::note +:::note Tested Deployments This demo was last tested on 2023 October 01. @@ -39,7 +39,7 @@ This demo was last tested on 2023 October 01. ## Lambda Functions -AWS offers the NodeJS runtime for JavaScript serverless function.[^1] +AWS offers NodeJS runtimes for running JavaScript serverless functions.[^1] The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be required in Lambda functions. When deploying, the entire `node_modules` folder diff --git a/docz/docs/03-demos/09-cloud/12-azure.md b/docz/docs/03-demos/30-cloud/12-azure.md similarity index 94% rename from docz/docs/03-demos/09-cloud/12-azure.md rename to docz/docs/03-demos/30-cloud/12-azure.md index 5cca6b2..9350892 100644 --- a/docz/docs/03-demos/09-cloud/12-azure.md +++ b/docz/docs/03-demos/30-cloud/12-azure.md @@ -9,7 +9,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; -[Azure Cloud Services](https://azure.microsoft.com/) is a Cloud Services +[Azure Cloud Services](https://azure.microsoft.com/) is a cloud services platform which includes traditional virtual machine support, "Serverless Functions" and cloud storage. @@ -33,7 +33,7 @@ will be available in the future. ::: -:::note +:::note Tested Deployments This demo was last tested on 2023 October 06. @@ -123,13 +123,39 @@ option was not required. ### Reading Data -Using `@azure/functions`, the handler callback receives a `Request` object. With -standard JS operations, the file can be pulled into an `ArrayBuffer` object. +Using `@azure/functions`, the handler callback receives a `Request` object. +Uploaded files can be pulled into `ArrayBuffer` objects. + +
Code Snippet (click to show) + +This function returns a promise that resolves to an `ArrayBuffer` object: + +```js +const { Blob } = require('buffer'); + +async function get_file_from_request(request, form_field_name) { + /* parse the request body */ + const formData = await request.formData(); + + /* pull the specified field */ + const file = formData.get(form_field_name); + + /* if a file was submitted, `file` will be a Blob */ + if(!(file instanceof Blob)) throw new Error(`File is missing!`); + + /* pull data into an ArrayBuffer object */ + const ab = await file.arrayBuffer(); + return ab; +} +``` + +
The SheetJS `read` method[^2] can read the `ArrayBuffer` objects and generate SheetJS workbook objects[^3] which can be processed with other API functions. -For example, a handler can use `sheet_to_csv`[^4] to generate CSV text: +For example, a handler can use `sheet_to_csv`[^4] to generate CSV text from +user-submitted spreadsheets: ```js const { Blob } = require('buffer'); @@ -143,6 +169,7 @@ app.http('SheetJSAzure', { const formData = await req.formData(); const f = formData.get("upload"); + /* if a file was submitted, `f` will be a Blob object */ if(!(f instanceof Blob)) return { status: 400, body: "Must submit a file" }; /* parse file */ diff --git a/docz/docs/03-demos/09-cloud/18-github.md b/docz/docs/03-demos/30-cloud/18-github.md similarity index 89% rename from docz/docs/03-demos/09-cloud/18-github.md rename to docz/docs/03-demos/30-cloud/18-github.md index b8ebc5e..c61fb00 100644 --- a/docz/docs/03-demos/09-cloud/18-github.md +++ b/docz/docs/03-demos/30-cloud/18-github.md @@ -60,17 +60,17 @@ As a project from the company, the entire lifecycle uses GitHub offerings: - GitHub offers free hosting for Git repositories - GitHub Actions[^1] infrastructure runs tasks at regular intervals -- `githubocto/flat`[^2] Action to help fetch data and automate post-processing -- `flat-postprocessing`[^3] Post-processing helper functions and examples -- "Flat Viewer"[^4]: Web viewer for structured CSV and JSON data on GitHub +- `githubocto/flat`[^2] library helps fetch data and automate post-processing +- `flat-postprocessing`[^3] library provides post-processing helper functions +- "Flat Viewer"[^4] displays structured CSV and JSON data from Git repositories :::caution pass -A GitHub account is required. When the demo was tested, free GitHub accounts had -no Actions usage limits for public repositories. +A GitHub account is required. When the demo was last tested, "GitHub Free" +accounts had no Actions usage limits for public repositories[^5]. -Using private GitHub repositories is not recommended because the Flat Viewer -cannot access private repositories. +Private GitHub repositories can be used for processing data, but the Flat Viewer +will not be able to display private data. ::: @@ -143,12 +143,12 @@ for more details. The first argument to the post-processing script is the filename. -The SheetJS `readFile` method[^5] will read the file and generate a SheetJS -workbook object[^6]. After extracting the first worksheet, `sheet_to_csv`[^7] +The SheetJS `readFile` method[^6] will read the file and generate a SheetJS +workbook object[^7]. After extracting the first worksheet, `sheet_to_csv`[^8] generates a CSV string. After generating a CSV string, the string should be written to the filesystem -using `Deno.writeFileSync`[^8]. By convention, the CSV should preserve the file +using `Deno.writeFileSync`[^9]. By convention, the CSV should preserve the file name stem and replace the extension with `.csv`: {`\ @@ -179,7 +179,7 @@ Deno.writeFileSync(out_file, new TextEncoder().encode(csv));`} ## Complete Example -:::note +:::note Tested Deployments This was last tested by SheetJS users on 2023 September 24 using the GitHub UI. @@ -321,7 +321,8 @@ jobs: [^2]: See [`githubocto/flat`](https://github.com/githubocto/flat) repo on GitHub. [^3]: See [`githubocto/flat-postprocessing`](https://github.com/githubocto/flat-postprocessing) repo on GitHub. [^4]: The hosted version is available at -[^5]: See [`readFile` in "Reading Files"](/docs/api/parse-options) -[^6]: See ["Workbook Object"](/docs/csf/book) -[^7]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) -[^8]: See [`Deno.writeFileSync`](https://deno.land/api?s=Deno.writeFileSync) in the Deno Runtime APIs documentation. \ No newline at end of file +[^5]: See ["About billing for GitHub Actions"](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions) in the GitHub documentation. +[^6]: See [`readFile` in "Reading Files"](/docs/api/parse-options) +[^7]: See ["Workbook Object"](/docs/csf/book) +[^8]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) +[^9]: See [`Deno.writeFileSync`](https://deno.land/api?s=Deno.writeFileSync) in the Deno Runtime APIs documentation. \ No newline at end of file diff --git a/docz/docs/03-demos/09-cloud/19-deno.md b/docz/docs/03-demos/30-cloud/19-deno.md similarity index 95% rename from docz/docs/03-demos/09-cloud/19-deno.md rename to docz/docs/03-demos/30-cloud/19-deno.md index 8eb9005..cab3826 100644 --- a/docz/docs/03-demos/09-cloud/19-deno.md +++ b/docz/docs/03-demos/30-cloud/19-deno.md @@ -16,8 +16,8 @@ data from spreadsheets. This demo covers integration details. We'll explore how to load and use SheetJS scripts in Deno Deploy functions. -The ["Demo"](#demo) section includes build a sample service that converts XLSX -and other types of spreadsheets to HTML tables and CSV rows. +The ["Demo"](#demo) section builds a sample service that converts XLSX and other +types of spreadsheets to HTML tables and CSV rows. :::caution pass @@ -25,7 +25,7 @@ When the demo was last tested, Deno Deploy required a GitHub account. ::: -:::note +:::note Tested Deployments This demo was last tested by SheetJS users on 2023 October 18. diff --git a/docz/docs/03-demos/09-cloud/21-gsheet.md b/docz/docs/03-demos/30-cloud/21-gsheet.md similarity index 95% rename from docz/docs/03-demos/09-cloud/21-gsheet.md rename to docz/docs/03-demos/30-cloud/21-gsheet.md index dd7f49f..ffa781c 100644 --- a/docz/docs/03-demos/09-cloud/21-gsheet.md +++ b/docz/docs/03-demos/30-cloud/21-gsheet.md @@ -54,8 +54,8 @@ referenced APIs will be available in the future. This demo uses the following NodeJS modules: -- `google-auth-library`[^1] to authenticate with Google APIs -- `node-google-spreadsheet`[^2] to interact with Google Sheets v4 API +- `google-auth-library`[^1] simplifies authentication with Google APIs +- `node-google-spreadsheet`[^2] interacts with Google Sheets v4 API :::info Initial Setup @@ -70,7 +70,10 @@ It is strongly recommended to use a service account for Google API operations. The ["Service Account Setup" section](#service-account-setup) covers how to create a service account and generate a JSON key file. -```js title="Authenticate using a JSON key file" +The generated JSON key file includes `client_email` and `private_key` fields. +These fields can be used in JWT authentication: + +```js title="JWT Authentication using a JSON key file" import { JWT } from 'google-auth-library' import { GoogleSpreadsheet } from 'google-spreadsheet'; @@ -331,7 +334,7 @@ At this point `wb` is a SheetJS workbook object[^7]. ## Complete Example -:::note +:::note Tested Deployments This demo was last tested on 2023 September 17 using `google-auth-library` for authentication (`v8.9.0`) and `google-spreadsheet` for API access (`v4.1.0`). diff --git a/docz/docs/03-demos/09-cloud/22-airtable.md b/docz/docs/03-demos/30-cloud/22-airtable.md similarity index 57% rename from docz/docs/03-demos/09-cloud/22-airtable.md rename to docz/docs/03-demos/30-cloud/22-airtable.md index 0e0f576..6ed06c5 100644 --- a/docz/docs/03-demos/09-cloud/22-airtable.md +++ b/docz/docs/03-demos/30-cloud/22-airtable.md @@ -24,44 +24,85 @@ libraries and appended to a dataset in Airtable ## NodeJS Integration -Airtable recommends Personal Access Tokens for interacting with their API. When -fetching data from the API, the result will include an array of row objects that -can be converted to a worksheet with `XLSX.utils.json_to_sheet`. The API methods -to write data will accept row objects generated by `XLSX.utils.sheet_to_json`. +### Installation -The main module is `airtable` and can be installed with `npm`: +The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be +required in NodeJS scripts that interact with Airtable. + +The Airtable connector module is `airtable` and can be installed with `npm`: {`\ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz airtable`} -To obtain a reference to a table, code needs a [PAT](#personal-access-token), -the name of the workspace (typically starting with `app`), and the name of the -desired table (the Excel import typically supports the worksheet name): +### Authentication + +Airtable recommends Personal Access Tokens ("PAT") for interacting with the API. + +:::note pass + +The ["Personal Access Token"](#personal-access-token) section walks through the +process of creating a PAT. + +::: + +The connector constructor accepts an options argument. The PAT should be passed +using the `apiKey` property: ```js -const Airtable = require("airtable"), XLSX = require("xlsx"); -/* query all records in a table */ -const conn = new Airtable({apiKey: "PAT...", /* and other options ... */}); -const table = conn.base("app...").table("tablename..."); +const Airtable = require("airtable"); +const apiKey = "PAT..."; // personal access token +const conn = new Airtable({apiKey, /* see docs for other options ... */}); +``` + +The `base` method opens a specified workspace. The internal workspace name is +the first fragment in the Airtable URL, typically starts with "app": + +```js +const base = conn.base("app..."); +``` + +The `table` method of the workspace object opens a specified table: + +```js +const table = base.table("tablename..."); ``` ### Exporting Data When querying data, a result set will be a simple array of Record objects. The -`fields` property is a simple JS object compatible with `json_to_sheet`: +`fields` property of each record object is a simple JS object. Mapping over the +result set and picking the `fields` field yields a standard array of objects: ```js -/** Create SheetJS worksheet from Airtable table */ -async function airtable_to_worksheet(table) { +/** Create array of objects from Airtable table */ +async function airtable_to_aoo(table) { /* get all rows */ const result = await table.select().all(); /* pull raw objects from the result */ // highlight-next-line const aoo = result.map(r => r.fields); + return aoo; +} +``` + +The SheetJS `json_to_sheet` utility function[^1] can generate a worksheet object +from the array of objects: + +```js +const XLSX = require("xlsx"); + +/** Create SheetJS worksheet from Airtable table */ +async function airtable_to_worksheet(table) { + /* get all rows */ + const result = await table.select().all(); + + /* pull raw objects from the result */ + const aoo = result.map(r => r.fields); /* create a worksheet */ + // highlight-next-line const worksheet = XLSX.utils.json_to_sheet(aoo); return worksheet; } @@ -74,17 +115,43 @@ for sorting by fields. ::: -### Importing Data - -When inserting records, each object should be wrapped in a parent object with a -single `fields` property: +The worksheet object must be added to a new workbook object using the `book_new` +and `book_append_sheet` helper functions[^2]: ```js -/** Append records from a SheetJS worksheet to Airtable table */ -async function airtable_load_worksheet(table, worksheet) { - /* suppose the field names */ - const aoo = XLSX.utils.sheet_to_json(worksheet); +/** Create SheetJS workbook from Airtable table */ +async function airtable_to_workbook(table) { + /* generate worksheet */ + const ws = await airtable_to_worksheet(table); + /* create a new workbook */ + const wb = XLSX.utils.book_new(); + /* add worksheet to workbook */ + XLSX.utils.book_append_sheet(wb, ws, "ExportedData"); + return wb; +} +``` +Local files can be created using the SheetJS `writeFile` method[^3]: + +```js +(async() => { + /* generate SheetJS workbook */ + const wb = await airtable_to_workbook(table); + /* write to XLSX */ + XLSX.writeFile(wb, "SheetJSAirtableExport.xlsx"); +})(); +``` + +### Importing Data + +The Airtable table `create` method expects an array of record objects. The +`fields` property of each object is expected to contain the raw record data. + +Mapping over a standard array of objects can create Airtable-friendly data: + +```js +/** Append records from an array of data objects to Airtable table */ +async function airtable_load_aoo(table, aoo) { /* reshape to be compatible with Airtable API */ // highlight-next-line const airtable_rows = aoo.map(fields => ({ fields })); @@ -94,9 +161,50 @@ async function airtable_load_worksheet(table, worksheet) { } ``` +Starting from a SheetJS worksheet object[^4], the `sheet_to_json` method[^5] can +generate normal arrays of objects: + +```js +const XLSX = require("xlsx"); + +/** Append records from a SheetJS worksheet to Airtable table */ +async function airtable_load_worksheet(table, worksheet) { + /* generate normal array of objects */ + // highlight-next-line + const aoo = XLSX.utils.sheet_to_json(worksheet); + + /* upload data */ + return await airtable_load_aoo(table, aoo); +} +``` + +A SheetJS worksheet object can be extracted from a workbook object[^6]: + +```js +/** Append records from the first worksheet of a workbook to Airtable table */ +async function airtable_load_workbook(table, workbook) { + /* pull first worksheet from workbook object */ + // highlight-next-line + const first_sheet_name = workbook.SheetNames[0]; + const ws = workbook.Sheets[first_sheet_name]; + + /* upload data */ + return await airtable_load_worksheet(table, ws); +} +``` + +Local files can be read using the SheetJS `readFile` method[^7]: + +```js +const wb = XLSX.readFile("SheetJSAirtableTest.xlsb"); +(async() => { + await airtable_load_workbook(table, wb); +}); +``` + ## Complete Example -:::note +:::note Tested Deployments This demo was last tested on 2023 September 03. At the time, free accounts included limited API access. @@ -240,4 +348,12 @@ node SheetJSAirtableWrite.js Open Airtable and verify the new row was added: -![Final Result in Airtable](pathname:///airtable/post.png) \ No newline at end of file +![Final Result in Airtable](pathname:///airtable/post.png) + +[^1]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input) +[^2]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`. +[^3]: See [`writeFile` in "Writing Files"](/docs/api/write-options) +[^4]: See ["Sheet Objects"](/docs/csf/sheet) for more details/ +[^5]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) +[^6]: See ["Workbook Object"](/docs/csf/book) +[^7]: See [`readFile` in "Reading Files"](/docs/api/parse-options) diff --git a/docz/docs/03-demos/09-cloud/31-dropbox.mdx b/docz/docs/03-demos/30-cloud/31-dropbox.mdx similarity index 97% rename from docz/docs/03-demos/09-cloud/31-dropbox.mdx rename to docz/docs/03-demos/30-cloud/31-dropbox.mdx index 028c225..97263c0 100644 --- a/docz/docs/03-demos/09-cloud/31-dropbox.mdx +++ b/docz/docs/03-demos/30-cloud/31-dropbox.mdx @@ -6,7 +6,7 @@ pagination_next: demos/extensions/index --- - + [Dropbox](https://www.dropbox.com/) is a file hosting service that offers APIs @@ -34,7 +34,7 @@ their Dropbox account. This demo will generate a XLS workbook using SheetJS. The Dropbox API script is loaded in this page with ```html - + ``` The `data-app-key` used in this demo is a "Development" key associated with the @@ -262,9 +262,9 @@ function SheetJSEnregistrez() { ## Dropbox App -:::note +:::note Tested Deployments -This demo was last tested on 2023 August 26. +This demo was last tested on 2023 November 30. ::: diff --git a/docz/docs/03-demos/09-cloud/_category_.json b/docz/docs/03-demos/30-cloud/_category_.json similarity index 64% rename from docz/docs/03-demos/09-cloud/_category_.json rename to docz/docs/03-demos/30-cloud/_category_.json index 5d81b5a..e0abe14 100644 --- a/docz/docs/03-demos/09-cloud/_category_.json +++ b/docz/docs/03-demos/30-cloud/_category_.json @@ -1,4 +1,4 @@ { "label": "Cloud Platforms", - "position": 9 + "position": 30 } \ No newline at end of file diff --git a/docz/docs/03-demos/09-cloud/index.md b/docz/docs/03-demos/30-cloud/index.md similarity index 100% rename from docz/docs/03-demos/09-cloud/index.md rename to docz/docs/03-demos/30-cloud/index.md