diff --git a/docz/docs/02-getting-started/02-examples/04-import.md b/docz/docs/02-getting-started/02-examples/04-import.md index da6053f..fea541b 100644 --- a/docz/docs/02-getting-started/02-examples/04-import.md +++ b/docz/docs/02-getting-started/02-examples/04-import.md @@ -1064,7 +1064,7 @@ When the app is loaded, the data will be displayed in rows. -[^1]: is the current location for the CC0-licensed dataset. `PortfolioSummary.xls` is the file name. +[^1]: The dataset URL has changed many times over the years. The current location for the CC0-licensed dataset can be found by [searching for "National Student Loan Data System" on `data.gov`](https://catalog.data.gov/dataset/?q=national+student+loan+data+system&publisher=Office+of+Federal+Student+Aid+%28FSA%29&organization=ed-gov). `PortfolioSummary.xls` is the file name within the dataset. [^2]: See [`read` in "Reading Files"](/docs/api/parse-options) [^3]: See ["SheetJS Data Model"](/docs/csf/) [^4]: See ["Workbook Object"](/docs/csf/book) diff --git a/docz/docs/03-demos/01-frontend/01-react.md b/docz/docs/03-demos/01-frontend/01-react.md index 48128ca..e851641 100644 --- a/docz/docs/03-demos/01-frontend/01-react.md +++ b/docz/docs/03-demos/01-frontend/01-react.md @@ -159,12 +159,19 @@ import { read, utils } from 'xlsx'; /* Fetch and update the state once */ useEffect(() => { (async() => { - /* Download file */ - const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer(); + /* Download from https://sheetjs.com/pres.numbers */ + const f = await fetch("https://sheetjs.com/pres.numbers"); + const ab = await f.arrayBuffer(); + // highlight-start - const wb = read(f); // parse the array buffer + /* parse */ + const wb = read(ab); + + /* generate array of objects from first worksheet */ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet const data = utils.sheet_to_json(ws); // generate objects + + /* update state */ setPres(data); // update state // highlight-end })(); }, []); @@ -179,12 +186,19 @@ import { read, utils } from 'xlsx'; /* Fetch and update the state once */ useEffect(() => { (async() => { - /* Download file */ - const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer(); + /* Download from https://sheetjs.com/pres.numbers */ + const f = await fetch("https://sheetjs.com/pres.numbers"); + const ab = await f.arrayBuffer(); + // highlight-start - const wb = read(f); // parse the array buffer + /* parse */ + const wb = read(ab); + + /* generate array of presidents from the first worksheet */ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet const data: President[] = utils.sheet_to_json(ws); // generate objects + + /* update state */ setPres(data); // update state // highlight-end })(); }, []); @@ -305,6 +319,57 @@ export default function SheetJSReactAoO() {
How to run the example (click to show) + + + +:::note + +This demo was last tested on 2023 October 08 with ViteJS 4.4.1 and React 18.2.0 + +::: + +1) Create a new site: + +```bash +npm create vite@latest sheetjs-react -- --template react +``` + +2) Install the SheetJS dependency and start the dev server: + +{`\ +cd sheetjs-react +npm i +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz +npm run dev`} + + +3) Open a web browser and access the displayed URL (`http://localhost:5173`) + +4) Replace `src/App.jsx` with the `src/SheetJSReactAoO.js` example. + +The page will refresh and show a table with an Export button. Click the button +and the page will attempt to download `SheetJSReactAoA.xlsx`. + +5) Build the site: + +```bash +npm run build +``` + +The generated site will be placed in the `dist` folder. + +6) Start a local web server: + +```bash +npx http-server dist +``` + +Access the displayed URL (typically `http://localhost:8080`) with a web browser +and test the page. + + + + :::note This demo was last run on 2023 July 03 using `create-react-app@5.0.1` and @@ -334,8 +399,25 @@ npm start`} The page will refresh and show a table with an Export button. Click the button and the page will attempt to download `SheetJSReactAoA.xlsx`. -5) Build the site with `npm run build`, then test with `npx http-server build`. -Access `http://localhost:8080` with a web browser to test the bundled site. +5) Build the site: + +```bash +npm run build +``` + +The generated site will be placed in the `build` folder. + +6) Start a local web server: + +```bash +npx http-server build +``` + +Access the displayed URL (typically `http://localhost:8080`) with a web browser +and test the page. + + +
@@ -394,6 +476,57 @@ export default function SheetJSReactHTML() {
How to run the example (click to show) + + + +:::note + +This demo was last tested on 2023 October 08 with ViteJS 4.4.1 and React 18.2.0 + +::: + +1) Create a new site: + +```bash +npm create vite@latest sheetjs-react -- --template react +``` + +2) Install the SheetJS dependency and start the dev server: + +{`\ +cd sheetjs-react +npm i +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz +npm run dev`} + + +3) Open a web browser and access the displayed URL (`http://localhost:5173`) + +4) Replace `src/App.jsx` with the `src/SheetJSReactHTML.js` example. + +The page will refresh and show a table with an Export button. Click the button +and the page will attempt to download `SheetJSReactHTML.xlsx`. + +5) Build the site: + +```bash +npm run build +``` + +The generated site will be placed in the `dist` folder. + +6) Start a local web server: + +```bash +npx http-server dist +``` + +Access the displayed URL (typically `http://localhost:8080`) with a web browser +and test the page. + + + + :::note This demo was last run on 2023 July 03 using `create-react-app@5.0.1` and @@ -423,8 +556,25 @@ npm start`} The page will refresh and show a table with an Export button. Click the button and the page will attempt to download `SheetJSReactHTML.xlsx`. -5) Build the site with `npm run build`, then test with `npx http-server build`. -Access `http://localhost:8080` with a web browser to test the bundled site. +5) Build the site: + +```bash +npm run build +``` + +The generated site will be placed in the `build` folder. + +6) Start a local web server: + +```bash +npx http-server build +``` + +Access the displayed URL (typically `http://localhost:8080`) with a web browser +and test the page. + + +
diff --git a/docz/docs/03-demos/01-frontend/02-vue.md b/docz/docs/03-demos/01-frontend/02-vue.md index 6b224a3..fd70559 100644 --- a/docz/docs/03-demos/01-frontend/02-vue.md +++ b/docz/docs/03-demos/01-frontend/02-vue.md @@ -54,27 +54,17 @@ depends on the application. Typically, some users will create a spreadsheet with source data that should be loaded into the site. This sheet will have known columns. -For example, our [presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" and "Index" columns: +#### State + +The example [presidents sheet](https://sheetjs.com/pres.xlsx) has one header row +with "Name" and "Index" columns. The natural JS representation is an object for +each row, using the values in the first rows as keys: + +
SpreadsheetState
![`pres.xlsx` data](pathname:///pres.png) -This naturally maps to an array of typed objects, as in the TS example below: - -```ts -import { read, utils } from 'xlsx'; - -interface President { - Name: string; - Index: number; -} - -const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer(); -const wb = read(f); -const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); -console.log(data); -``` - -`data` will be an array of objects: + ```js [ @@ -86,8 +76,234 @@ console.log(data); ] ``` -A component will typically map over the data. The following example generates -a TABLE with a row for each President: +
+ +Using the VueJS Composition API, the `ref`[^1] function creates state objects: + + + + +```html + +``` + + + + +```html + +``` + +When the spreadsheet header row is known ahead of time, row typing is possible: + +```html + +``` + +:::caution pass + +The types are informative. They do not enforce that worksheets include the named +columns. A runtime data validation library should be used to verify the dataset. + +When the file header is not known in advance, `any` should be used. + +::: + + + + +#### Updating State + +The SheetJS [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output) +functions simplify state updates. They are best used in the function bodies of +lifecycle hooks including `onMounted`[^2]. + +The `onMounted` hook can download and update state when a person loads the site: + +```mermaid +flowchart LR + url[(Remote\nFile)] + ab[(Data\nArrayBuffer)] + wb(SheetJS\nWorkbook) + ws(SheetJS\nWorksheet) + aoo(array of\nobjects) + state((component\nstate)) + url --> |fetch\n\n| ab + ab --> |read\n\n| wb + wb --> |wb.Sheets\nselect sheet| ws + ws --> |sheet_to_json\n\n| aoo + aoo --> |setPres\nfrom `setState`| state +``` + + + + +```html + +``` + + + + +```html + +``` + + + + +#### Rendering Data + +A component will typically map over the data with `v-for`[^3]. The following +example generates a TABLE with a row for each President: + +```html title="Example SFC for displaying arrays of objects" + + + +``` + +#### Exporting Data + +The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input) +functions simplify exporting data. They are best used in the function bodies of +`v-on` event handlers like `@click`[^4]. + +A callback can generate a local file when a user clicks a button: + +```mermaid +flowchart LR + state((component\nstate)) + ws(SheetJS\nWorksheet) + wb(SheetJS\nWorkbook) + file[(XLSX\nexport)] + state --> |json_to_sheet\n\n| ws + ws --> |book_new\nbook_append_sheet| wb + wb --> |writeFile\n\n| file +``` + +```html + + + +``` + +#### Complete Component + +This complete component example fetches a test file and displays the contents in +a HTML table. When the export button is clicked, a callback will export a file: ```html title="src/SheetJSVueAoO.vue"