forked from sheetjs/docs.sheetjs.com
		
	new-dataset-url
This commit is contained in:
		
							parent
							
								
									990f42934b
								
							
						
					
					
						commit
						5d87422b97
					
				@ -1064,7 +1064,7 @@ When the app is loaded, the data will be displayed in rows.
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
[^1]: <https://catalog.data.gov/dataset/national-student-loan-data-system-aa85f> 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)
 | 
			
		||||
 | 
			
		||||
@ -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<President>(ws); // generate objects
 | 
			
		||||
 | 
			
		||||
  /* update state */
 | 
			
		||||
  setPres(data); // update state
 | 
			
		||||
  // highlight-end
 | 
			
		||||
})(); }, []);
 | 
			
		||||
@ -305,6 +319,57 @@ export default function SheetJSReactAoO() {
 | 
			
		||||
 | 
			
		||||
<details open><summary><b>How to run the example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="starter">
 | 
			
		||||
  <TabItem name="vite" value="ViteJS">
 | 
			
		||||
 | 
			
		||||
:::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:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
cd sheetjs-react
 | 
			
		||||
npm i
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
 | 
			
		||||
npm run dev`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem name="CRA" value="create-react-app">
 | 
			
		||||
 | 
			
		||||
:::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.
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
@ -394,6 +476,57 @@ export default function SheetJSReactHTML() {
 | 
			
		||||
 | 
			
		||||
<details open><summary><b>How to run the example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="starter">
 | 
			
		||||
  <TabItem name="vite" value="ViteJS">
 | 
			
		||||
 | 
			
		||||
:::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:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
cd sheetjs-react
 | 
			
		||||
npm i
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
 | 
			
		||||
npm run dev`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem name="CRA" value="create-react-app">
 | 
			
		||||
 | 
			
		||||
:::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.
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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:
 | 
			
		||||
 | 
			
		||||
<table><thead><tr><th>Spreadsheet</th><th>State</th></tr></thead><tbody><tr><td>
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
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<President>(wb.Sheets[wb.SheetNames[0]]);
 | 
			
		||||
console.log(data);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`data` will be an array of objects:
 | 
			
		||||
</td><td>
 | 
			
		||||
 | 
			
		||||
```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:
 | 
			
		||||
</td></tr></tbody></table>
 | 
			
		||||
 | 
			
		||||
Using the VueJS Composition API, the `ref`[^1] function creates state objects:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="lang">
 | 
			
		||||
  <TabItem name="JS" value="JavaScript">
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script setup>
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of objects */
 | 
			
		||||
const pres = ref([]);
 | 
			
		||||
</script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem name="TS" value="TypeScript" default>
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of objects */
 | 
			
		||||
const pres = ref<any[]>([]);
 | 
			
		||||
</script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When the spreadsheet header row is known ahead of time, row typing is possible:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
 | 
			
		||||
interface President {
 | 
			
		||||
  Name: string;
 | 
			
		||||
  Index: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of presidents */
 | 
			
		||||
const pres = ref<President[]>([]);
 | 
			
		||||
</script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::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.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
#### 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
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="lang">
 | 
			
		||||
  <TabItem name="JS" value="JavaScript">
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script setup>
 | 
			
		||||
import { ref, onMounted } from "vue";
 | 
			
		||||
import { read, utils } from 'xlsx';
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of objects */
 | 
			
		||||
const pres = ref([]);
 | 
			
		||||
 | 
			
		||||
/* Fetch and update the state once */
 | 
			
		||||
onMounted(async() => {
 | 
			
		||||
  /* Download from https://sheetjs.com/pres.numbers */
 | 
			
		||||
  const f = await fetch("https://sheetjs.com/pres.numbers");
 | 
			
		||||
  const ab = await f.arrayBuffer();
 | 
			
		||||
 | 
			
		||||
  // highlight-start
 | 
			
		||||
  /* 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 */
 | 
			
		||||
  pres.value = data;
 | 
			
		||||
  // highlight-end
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem name="TS" value="TypeScript" default>
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, onMounted } from "vue";
 | 
			
		||||
import { read, utils } from 'xlsx';
 | 
			
		||||
 | 
			
		||||
interface President {
 | 
			
		||||
  Name: string;
 | 
			
		||||
  Index: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of presidents */
 | 
			
		||||
const pres = ref<President[]>([]);
 | 
			
		||||
 | 
			
		||||
/* Fetch and update the state once */
 | 
			
		||||
onMounted(async() => {
 | 
			
		||||
  /* Download from https://sheetjs.com/pres.numbers */
 | 
			
		||||
  const f = await fetch("https://sheetjs.com/pres.numbers");
 | 
			
		||||
  const ab = await f.arrayBuffer();
 | 
			
		||||
 | 
			
		||||
  // highlight-start
 | 
			
		||||
  /* 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<President>(ws); // generate objects
 | 
			
		||||
 | 
			
		||||
  /* update state */
 | 
			
		||||
  pres.value = data;
 | 
			
		||||
  // highlight-end
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
#### 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"
 | 
			
		||||
<script setup>
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
const rows = ref([]);
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
<table>
 | 
			
		||||
  <!-- The `thead` section includes the table header row -->
 | 
			
		||||
  <thead><th>Name</th><th>Index</th></thead>
 | 
			
		||||
  <!-- The `tbody` section includes the data rows -->
 | 
			
		||||
  <tbody>
 | 
			
		||||
    <!-- generate row (TR) for each president -->
 | 
			
		||||
    <!-- highlight-start-->
 | 
			
		||||
    <tr v-for="(row, idx) in rows" :key="idx">
 | 
			
		||||
      <td>{{ row.Name }}</td>
 | 
			
		||||
      <td>{{ row.Index }}</td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <!-- highlight-end-->
 | 
			
		||||
  </tbody>
 | 
			
		||||
</table>
 | 
			
		||||
</template>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 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
 | 
			
		||||
<script setup>
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { utils, writeFileXLSX } from 'xlsx';
 | 
			
		||||
 | 
			
		||||
const pres = ref([]);
 | 
			
		||||
 | 
			
		||||
/* get state data and export to XLSX */
 | 
			
		||||
function exportFile() {
 | 
			
		||||
  /* generate worksheet from state */
 | 
			
		||||
  // highlight-next-line
 | 
			
		||||
  const ws = utils.json_to_sheet(pres.value);
 | 
			
		||||
  /* create workbook and append worksheet */
 | 
			
		||||
  const wb = utils.book_new();
 | 
			
		||||
  utils.book_append_sheet(wb, ws, "Data");
 | 
			
		||||
  /* export to XLSX */
 | 
			
		||||
  writeFileXLSX(wb, "SheetJSVueAoO.xlsx");
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <button @click="exportFile">Export XLSX</button>
 | 
			
		||||
</template>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### 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"
 | 
			
		||||
<script setup>
 | 
			
		||||
@ -157,8 +373,22 @@ The page will refresh and show a table with an Export button.  Click the button
 | 
			
		||||
and the page will attempt to download `SheetJSVueAoA.xlsx`. There may be a delay
 | 
			
		||||
since Vite will try to optimize the SheetJS library on the fly.
 | 
			
		||||
 | 
			
		||||
5) Build the site with `npm run build`, then test with `npx http-server dist`.
 | 
			
		||||
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 `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.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
@ -168,9 +398,14 @@ The main disadvantage of the Array of Objects approach is the specific nature
 | 
			
		||||
of the columns.  For more general use, passing around an Array of Arrays works.
 | 
			
		||||
However, this does not handle merge cells well!
 | 
			
		||||
 | 
			
		||||
The `sheet_to_html` function generates HTML that is aware of merges and other
 | 
			
		||||
worksheet features.  VueJS `v-html` attribute allows assignment of `innerHTML`
 | 
			
		||||
attribute, effectively inserting the code into the page:
 | 
			
		||||
The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function
 | 
			
		||||
generates HTML that is aware of merges and other worksheet features.  VueJS
 | 
			
		||||
`v-html`[^5] attribute allows code to set the `innerHTML` attribute, effectively
 | 
			
		||||
inserting the code into the page.
 | 
			
		||||
 | 
			
		||||
In this example, the component attaches a `ref` to the `DIV` container. During
 | 
			
		||||
export, the first `TABLE` child element can be parsed with [`table_to_book`](/docs/api/utilities/html#html-table-input) to
 | 
			
		||||
generate a workbook object.
 | 
			
		||||
 | 
			
		||||
```html title="src/SheetJSVueHTML.vue"
 | 
			
		||||
<script setup>
 | 
			
		||||
@ -233,8 +468,40 @@ The page will refresh and show a table with an Export button.  Click the button
 | 
			
		||||
and the page will attempt to download `SheetJSVueHTML.xlsx`. There may be a delay
 | 
			
		||||
since Vite will try to optimize the SheetJS library on the fly.
 | 
			
		||||
 | 
			
		||||
5) Build the site with `npm run build`, then test with `npx http-server dist`.
 | 
			
		||||
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 `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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
@ -284,3 +551,9 @@ The entire demo is designed to run in Internet Explorer and does not reflect
 | 
			
		||||
modern design patterns.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
[^1]: See [`ref()`](https://vuejs.org/api/reactivity-core.html#ref) in the VueJS documentation.
 | 
			
		||||
[^2]: See [`onMounted()`](https://vuejs.org/api/composition-api-lifecycle.html#onmounted) in the VueJS documentation.
 | 
			
		||||
[^3]: See [`v-for`](https://vuejs.org/api/built-in-directives.html#v-for) in the VueJS documentation.
 | 
			
		||||
[^4]: See [`v-on`](https://vuejs.org/api/built-in-directives.html#v-on) in the VueJS documentation.
 | 
			
		||||
[^5]: See [`v-html`](https://vuejs.org/api/built-in-directives.html#v-html) in the VueJS documentation.
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
---
 | 
			
		||||
title: GatsbyJS
 | 
			
		||||
title: Spreadsheets in GatsbyJS Sites
 | 
			
		||||
sidebar_label: GatsbyJS
 | 
			
		||||
description: Make static websites from spreadsheets using GatsbyJS. Seamlessly integrate data into your website using SheetJS. Generate websites from data in Excel spreadsheets.
 | 
			
		||||
pagination_prev: demos/net/index
 | 
			
		||||
pagination_next: demos/mobile/index
 | 
			
		||||
sidebar_custom_props:
 | 
			
		||||
@ -7,21 +9,27 @@ sidebar_custom_props:
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import Tabs from '@theme/Tabs';
 | 
			
		||||
import TabItem from '@theme/TabItem';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
[GatsbyJS](https://www.gatsbyjs.com/) is a framework for creating websites. It
 | 
			
		||||
uses React components for page templates and GraphQL for loading data.
 | 
			
		||||
GatsbyJS is a framework for creating websites. It uses React components for page
 | 
			
		||||
templates and GraphQL for loading data.
 | 
			
		||||
 | 
			
		||||
[`gatsby-transformer-excel`](https://www.gatsbyjs.com/plugins/gatsby-transformer-excel/)
 | 
			
		||||
is a transformer that generates GraphQL nodes for each row of each worksheet.
 | 
			
		||||
The plugin is officially supported by the Gatsby team. The plugin documentation
 | 
			
		||||
includes examples and more detailed usage instructions.
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
This demo uses GatsbyJS and SheetJS (through the `gatsby-transformer-excel`[^1]
 | 
			
		||||
transformer) to pull data from a spreadsheet and display the content in a page.
 | 
			
		||||
 | 
			
		||||
The ["Complete Example"](#complete-example) section includes a complete website
 | 
			
		||||
powered by an XLSX spreadsheet.
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
`gatsby-transformer-excel` is maintained by the Gatsby core team and all bugs
 | 
			
		||||
should be directed to the main Gatsby project.  If it is determined to be a bug
 | 
			
		||||
in the parsing logic, issues should then be raised with the SheetJS project.
 | 
			
		||||
in the parsing logic, issues should then be raised with the SheetJS team.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -30,7 +38,7 @@ in the parsing logic, issues should then be raised with the SheetJS project.
 | 
			
		||||
`gatsby-transformer-excel` uses an older version of the library.  It can be
 | 
			
		||||
overridden through a `package.json` override in the latest versions of NodeJS:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="json">{`\
 | 
			
		||||
<CodeBlock language="json" title="package.json (add highlighted lines)">{`\
 | 
			
		||||
{
 | 
			
		||||
  "overrides": {
 | 
			
		||||
    "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
 | 
			
		||||
@ -40,11 +48,93 @@ overridden through a `package.json` override in the latest versions of NodeJS:
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## GraphQL details
 | 
			
		||||
:::warning Telemetry
 | 
			
		||||
 | 
			
		||||
`gatsby-transformer-excel` generates nodes for each data row of each worksheet.
 | 
			
		||||
Under the hood, it uses [`sheet_to_json`](/docs/api/utilities#array-output)
 | 
			
		||||
to generate row objects using the headers in the first row as keys.
 | 
			
		||||
GatsbyJS collects telemetry by default. The `telemetry` subcommand can disable it:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
npx gatsby telemetry --disable
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Integration Details
 | 
			
		||||
 | 
			
		||||
```mermaid
 | 
			
		||||
flowchart LR
 | 
			
		||||
  file[(workbook\nfile)]
 | 
			
		||||
  subgraph SheetJS operations
 | 
			
		||||
    filenode[File\nNode]
 | 
			
		||||
    datanode[Data\nNodes]
 | 
			
		||||
  end
 | 
			
		||||
  aoo(array of\nobjects)
 | 
			
		||||
  html{{HTML\nTABLE}}
 | 
			
		||||
  file --> |Source\nPlugin| filenode
 | 
			
		||||
  filenode --> |Transformer\nPlugin| datanode
 | 
			
		||||
  datanode --> |GraphQL\nQuery| aoo
 | 
			
		||||
  aoo --> |React\nJSX| html
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In the GatsbyJS data system, source plugins read from data sources and generate
 | 
			
		||||
nodes represent raw data. Transformer plugins transform these nodes into other
 | 
			
		||||
nodes that represent processed data for use in pages.
 | 
			
		||||
 | 
			
		||||
This example uses `gatsby-source-filesystem`[^2] to read files from the
 | 
			
		||||
filesystem and `gatsby-transformer-excel` transformer to perform the transform.
 | 
			
		||||
 | 
			
		||||
### Installation
 | 
			
		||||
 | 
			
		||||
The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) will be
 | 
			
		||||
referenced by `gatsby-transformer-excel`.
 | 
			
		||||
 | 
			
		||||
Before installing, to ensure that the transformer uses the latest version of the
 | 
			
		||||
library, the `overrides` section must be added to `package.json`:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="json" title="package.json (add highlighted lines)">{`\
 | 
			
		||||
{
 | 
			
		||||
  // highlight-start
 | 
			
		||||
  "overrides": {
 | 
			
		||||
    "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
 | 
			
		||||
  }
 | 
			
		||||
  // highlight-end
 | 
			
		||||
}`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
`gatsby-transformer-excel` and `gatsby-source-filesystem` should be installed
 | 
			
		||||
after installing SheetJS modules:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="pm">
 | 
			
		||||
  <TabItem value="npm" label="npm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npx gatsby telemetry --disable
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
 | 
			
		||||
npm i --save gatsby-transformer-excel gatsby-source-filesystem`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="pnpm" label="pnpm">
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npx gatsby telemetry --disable
 | 
			
		||||
pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
 | 
			
		||||
pnpm install gatsby-transformer-excel gatsby-source-filesystem`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="yarn" label="Yarn" default>
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npx gatsby telemetry --disable
 | 
			
		||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
 | 
			
		||||
yarn add gatsby-transformer-excel gatsby-source-filesystem`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
### GraphQL details
 | 
			
		||||
 | 
			
		||||
Under the hood, `gatsby-transformer-excel` uses the SheetJS `read`[^3] method to
 | 
			
		||||
parse the workbook into a SheetJS workbook[^4]. Each worksheet is extracted from
 | 
			
		||||
the workbook. The `sheet_to_json` method[^5] generates row objects using the
 | 
			
		||||
headers in the first row as keys.
 | 
			
		||||
 | 
			
		||||
Consider the following worksheet:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -78,18 +168,28 @@ The following query pulls the `Name` and `Index` fields from each row:
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## GatsbyJS Demo
 | 
			
		||||
## Complete Example
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was tested on 2023 September 13 against `create-gatsby@3.12.0`. The
 | 
			
		||||
generated project used `gatsby@5.12.4` and `react@18.2.0`.
 | 
			
		||||
This demo was tested on 2023 October 08 against `create-gatsby@3.12.0`. The
 | 
			
		||||
generated project used `gatsby@5.12.5` and `react@18.2.0`.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### Project setup
 | 
			
		||||
 | 
			
		||||
1) Run `npm init gatsby -- -y sheetjs-gatsby` to create the template site.
 | 
			
		||||
0) Disable GatsbyJS telemetry:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx gatsby telemetry --disable
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Create a template site:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npm init gatsby -- -y sheetjs-gatsby
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Follow the on-screen instructions for starting the local development server:
 | 
			
		||||
 | 
			
		||||
@ -157,7 +257,7 @@ Stop and restart the development server process (`npm run develop`).
 | 
			
		||||
 | 
			
		||||
### GraphiQL test
 | 
			
		||||
 | 
			
		||||
7) Open the GraphiQL editor at `http://localhost:8000/___graphql`.
 | 
			
		||||
7) Open the GraphiQL editor at `http://localhost:8000/___graphql`
 | 
			
		||||
 | 
			
		||||
There is an editor in the left pane.  Paste the following query into the editor:
 | 
			
		||||
 | 
			
		||||
@ -203,8 +303,8 @@ const PageComponent = ({data}) => {
 | 
			
		||||
export default PageComponent;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
After saving the file, access `http://localhost:8000/pres`.  The displayed JSON
 | 
			
		||||
is the data that the component receives:
 | 
			
		||||
After saving the file, access `http://localhost:8000/pres` in the browser. The
 | 
			
		||||
displayed JSON is the data that the component receives:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
{
 | 
			
		||||
@ -301,3 +401,9 @@ There will be a HTML row:
 | 
			
		||||
```html title="public/pres/index.html"
 | 
			
		||||
<tr><td>SheetJS Dev</td><td>47</td></tr>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[^1]: The package is available as [`gatsby-transformer-excel` on the public NPM registry](https://www.npmjs.com/package/gatsby-transformer-excel). It is also listed on the [GatsbyJS plugin library](https://www.gatsbyjs.com/plugins/gatsby-transformer-excel/).
 | 
			
		||||
[^2]: See [the `gatsby-source-filesystem` plugin](https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/) in the GatsbyJS documentation
 | 
			
		||||
[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
 | 
			
		||||
[^4]: See ["Workbook Object"](/docs/csf/book) for more details on the SheetJS workbook object.
 | 
			
		||||
[^5]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
 | 
			
		||||
@ -25,14 +25,15 @@ plugin and compare a few different data loading strategies.
 | 
			
		||||
The ["Complete Demo"](#complete-demo) section creates a complete website powered
 | 
			
		||||
by a XLSX spreadsheet.
 | 
			
		||||
 | 
			
		||||
:::tip pass
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
This demo covers use cases where data is available at build time. This flow is
 | 
			
		||||
suitable for end of week or end of month (EOM) reports published in HTML tables
 | 
			
		||||
suitable for end of week or end of month (EOM) reports published in HTML tables.
 | 
			
		||||
 | 
			
		||||
For processing user-submitted files in the browser, the
 | 
			
		||||
["Bundlers" demo](/docs/demos/frontend/bundler#vite) shows client-side bundling
 | 
			
		||||
of the SheetJS library.
 | 
			
		||||
of the SheetJS library. The ["ReactJS" demo](/docs/demos/frontend/react) shows
 | 
			
		||||
example sites using ViteJS with the ReactJS starter.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,10 +7,15 @@ pagination_next: demos/mobile/index
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
Eleventy is a static site generator.
 | 
			
		||||
[Eleventy](https://www.11ty.dev/docs) is a telemetry-free static site generator.
 | 
			
		||||
The data pipeline can be augmented with custom data file parsers.
 | 
			
		||||
 | 
			
		||||
The [NodeJS module](/docs/getting-started/installation/nodejs) can be loaded in
 | 
			
		||||
`.eleventy.js` and used in custom data file format parsers.
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses Eleventy and SheetJS to pull data from a spreadsheet and display
 | 
			
		||||
the content in a page. We'll explore how to load SheetJS libraries in a custom
 | 
			
		||||
data file format parser and generate arrays of objects for use in pages.
 | 
			
		||||
 | 
			
		||||
The following diagram depicts the workbook waltz:
 | 
			
		||||
 | 
			
		||||
@ -27,19 +32,33 @@ flowchart LR
 | 
			
		||||
  aoo --> |index.njk\ntemplate| html
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::tip No Telemetry
 | 
			
		||||
 | 
			
		||||
The author has publicly stated that Eleventy does not embed any telemetry or
 | 
			
		||||
data collection.[^1]
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Integration Details
 | 
			
		||||
 | 
			
		||||
The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be
 | 
			
		||||
loaded in `.eleventy.js` and used in custom data file format parsers.
 | 
			
		||||
 | 
			
		||||
### Data File Parser
 | 
			
		||||
 | 
			
		||||
Custom data file parsers must be registered in `.eleventy.js`
 | 
			
		||||
 | 
			
		||||
`addDataExtension` accepts a list of file extensions and a parser object.
 | 
			
		||||
The Eleventy config `addDataExtension` method[^2] accepts a list of file
 | 
			
		||||
extensions and a parser configuration object.
 | 
			
		||||
 | 
			
		||||
The parser object must include the options `read: true` and `encoding: null` .
 | 
			
		||||
Eleventy will read files and pass raw `Buffer` objects to the parser callback.
 | 
			
		||||
 | 
			
		||||
The `parser` callback can parse the data with `XLSX.read`. In this demo, the
 | 
			
		||||
parser will generate an array of row objects using `XLSX.utils.sheet_to_json`:
 | 
			
		||||
The `parser` callback can parse the raw `Buffer` data with the SheetJS `read`
 | 
			
		||||
method[^3]. The method returns a workbook object[^4].
 | 
			
		||||
 | 
			
		||||
In this example, the parser will use the SheetJS `sheet_to_json` method[^5] to
 | 
			
		||||
generate an array of objects from the data in the first worksheet:
 | 
			
		||||
 | 
			
		||||
```js title=".eleventy.js"
 | 
			
		||||
const XLSX = require("xlsx");
 | 
			
		||||
@ -91,7 +110,7 @@ using the variable `pres` in a template:
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was tested on 2023 May 07 using Eleventy `2.0.1`
 | 
			
		||||
This demo was tested on 2023 October 08 using Eleventy `2.0.1`
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -179,3 +198,9 @@ npx http-server _site
 | 
			
		||||
Open a web browser and access the displayed URL ( `http://localhost:8080` ).
 | 
			
		||||
View the page source and confirm that no JS was added to the page.  It only
 | 
			
		||||
contains the content from the file in an HTML table.
 | 
			
		||||
 | 
			
		||||
[^1]: See [the "Telemetry" section](https://www.zachleat.com/web/site-generator-review/#telemetry) of the site generator review from the author of Eleventy. When this page was last checked, the author proudly asserted that Eleventy had "No known Telemetry or data collection".
 | 
			
		||||
[^2]: See ["Custom Data File Formats"](https://www.11ty.dev/docs/data-custom/) in the Eleventy documentation.
 | 
			
		||||
[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
 | 
			
		||||
[^4]: See ["Workbook Object"](/docs/csf/book) for more details on the SheetJS workbook object.
 | 
			
		||||
[^5]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
 | 
			
		||||
@ -37,13 +37,11 @@ the browser refreshes to show the new content.
 | 
			
		||||
 | 
			
		||||
:::note Recommendation
 | 
			
		||||
 | 
			
		||||
It is strongly recommended to use a framework that provides an official plugin
 | 
			
		||||
for working with SheetJS.
 | 
			
		||||
It is strongly recommended to use a telemetry-free framework that provides an
 | 
			
		||||
official plugin for working with SheetJS.
 | 
			
		||||
 | 
			
		||||
Lume is a great choice for lightweight sites.
 | 
			
		||||
 | 
			
		||||
GatsbyJS is excellent for teams well-versed in the ReactJS framework.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### Official
 | 
			
		||||
 | 
			
		||||
@ -145,10 +145,6 @@ If the file does not exist, servers will send a 404 response that may include a
 | 
			
		||||
friendly HTML page. Without checking the response code, the integration will try
 | 
			
		||||
to read the 404 page and fail since the HTML typically has no TABLE elements.
 | 
			
		||||
 | 
			
		||||
When building a project with CRA or other templates, spreadsheets must be placed
 | 
			
		||||
in the `public` folder. That folder is served by the dev server and copied in
 | 
			
		||||
the build process.
 | 
			
		||||
 | 
			
		||||
Integration code should defend against network issues by checking status code.
 | 
			
		||||
For example, when using `fetch`:
 | 
			
		||||
 | 
			
		||||
@ -161,6 +157,14 @@ async function fetch_workbook_and_error_on_404(url) {
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
When building a project with `create-react-app` or other templates, spreadsheets
 | 
			
		||||
must be placed in the `public` folder. That folder is typically served by the
 | 
			
		||||
dev server and copied to the production site in the build process.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
#### Cloudflare Worker "Error: Script startup exceeded CPU time limit."
 | 
			
		||||
 | 
			
		||||
This may show up in projects with many dependencies. The official workaround is
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user