forked from sheetjs/docs.sheetjs.com
		
	dbox
This commit is contained in:
		
							parent
							
								
									f14874c930
								
							
						
					
					
						commit
						4770277d0b
					
				| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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: | ||||
| 
 | ||||
| @ -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: | ||||
| 
 | ||||
| @ -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 | | ||||
| 
 | ||||
| ::: | ||||
| @ -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 | | ||||
| 
 | ||||
| @ -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   | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -1,4 +1,4 @@ | ||||
| { | ||||
|   "label": "Local Data", | ||||
|   "position": 8 | ||||
|   "position": 27 | ||||
| } | ||||
| @ -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) | ||||
| [^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) | ||||
| @ -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. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -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 | ||||
| @ -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. | ||||
| 
 | ||||
| <details><summary><b>Code Snippet</b> (click to show)</summary> | ||||
| 
 | ||||
| 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; | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 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 */ | ||||
| @ -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`: | ||||
| 
 | ||||
| <CodeBlock title="postprocess.ts" language="ts">{`\ | ||||
| @ -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 <https://flatgithub.com/> | ||||
| [^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. | ||||
| [^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. | ||||
| @ -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. | ||||
| 
 | ||||
| @ -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`). | ||||
| @ -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`: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz airtable`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 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: | ||||
| 
 | ||||
|  | ||||
|  | ||||
| 
 | ||||
| [^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) | ||||
| @ -6,7 +6,7 @@ pagination_next: demos/extensions/index | ||||
| --- | ||||
| 
 | ||||
| <head> | ||||
|   <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="4ysmnhy8wtm6k3w"></script> | ||||
|   <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="6msofx0wc1zd7da"></script> | ||||
| </head> | ||||
| 
 | ||||
| [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 | ||||
| <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="4ysmnhy8wtm6k3w"></script> | ||||
| <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="6msofx0wc1zd7da"></script> | ||||
| ``` | ||||
| 
 | ||||
| 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. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -1,4 +1,4 @@ | ||||
| { | ||||
|   "label": "Cloud Platforms", | ||||
|   "position": 9 | ||||
|   "position": 30 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user