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:
|
||||
|
||||
![Final Result in Airtable](pathname:///airtable/post.png)
|
||||
![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)
|
@ -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