Demo refresh

This commit is contained in:
SheetJS 2025-05-12 00:41:16 -04:00
parent 1b242c12ef
commit 1f87dda979
40 changed files with 565 additions and 191 deletions

@ -644,7 +644,7 @@ After saving the file, run a local web server in the folder with the HTML file.
For example, if NodeJS is installed:
```bash
npx http-server .
npx -y http-server .
```
The server process will display a URL (typically `http://127.0.0.1:8080`). Open

@ -489,20 +489,20 @@ function SheetJSAoAFilled() {
### Select Data Rows
At this point, each data row will have the year in column `A` and dollar value
in column `C`. The year (first value in the row) will be between 2007 and 2024.
in column `C`. The year (first value in the row) will be between 2007 and 2029.
The value (third value) will be positive. The following function tests a row
against the requirements:
```js
const is_valid_row = r =>
r[0] >= 2007 && r[0] <= 2024 // year (column A) is between 2007 and 2024
r[0] >= 2007 && r[0] <= 2029 // year (column A) is between 2007 and 2029
&& r[2] > 0; // dollar value (column C) is positive
```
`Array#filter`, using the previous test, can select the matching rows:
```js
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
```
<details>
@ -522,7 +522,7 @@ function SheetJSAoAFiltered() {
var last_year = 0;
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
/* display data */
setRows(rows);
})(); }, []);
@ -598,7 +598,7 @@ function SheetJSObjects() {
var last_year = 0;
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
/* generate row objects */
const objects = rows.map(r => ({FY: r[0], FQ: r[1], total: r[8]}));
/* display data */
@ -706,7 +706,7 @@ function StudentAidTotal() {
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
/* generate row objects */
const objects = rows.map(r => ({FY: r[0], FQ: r[1], total: r[8]}));
@ -761,7 +761,7 @@ Save the following script to `SheetJSStandaloneDemo.html`:
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
\n\
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
\n\
/* generate row objects */
const objects = rows.map(r => ({FY: r[0], FQ: r[1], total: r[8]}));
@ -781,7 +781,7 @@ After saving the file, run a local web server in the folder with the HTML file.
For example, if NodeJS is installed:
```bash
npx http-server .
npx -y http-server .
```
The server process will display a URL (typically `http://127.0.0.1:8080`). Open
@ -827,7 +827,7 @@ const XLSX = require("xlsx");
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
/* generate row objects */
const objects = rows.map(r => ({FY: r[0], FQ: r[1], total: r[8]}));
@ -900,7 +900,7 @@ Save the following script to `SheetJSNW.html`:
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
\n\
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
\n\
/* generate row objects */
const objects = rows.map(r => ({FY: r[0], FQ: r[1], total: r[8]}));
@ -1001,7 +1001,7 @@ const App = () => {
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
/* select data rows */
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2024 && r[2] > 0);
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2029 && r[2] > 0);
/* generate row objects */
const objects = rows.map(r => ({FY: r[0], FQ: r[1], total: r[8]}));

@ -727,7 +727,7 @@ shape: (5, 2)
It will also export the DataFrame to `SheetJSPolars.xlsb`. The file can be
inspected with a spreadsheet editor that supports XLSB files.
[^1]: See ["Other Languages"](/docs/demos/engines/) for more examples.
[^1]: See ["JavaScript Engines"](/docs/demos/engines/) for more examples.
[^2]: See [`ctypes`](https://docs.python.org/3/library/ctypes.html) in the Python documentation.
[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^4]: See ["Workbook Object"](/docs/csf/book)

@ -518,7 +518,7 @@ The generated site will be placed in the `dist` folder.
9) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -665,7 +665,7 @@ The generated site will be placed in the `dist` folder.
9) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser

@ -135,7 +135,7 @@ The SheetJS [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/ut
functions simplify state updates. They are best used in the function bodies of
`useEffect`[^2] and `useCallback`[^3] hooks.
A `useEffect` hook can download and update state when a person loads the site:
A `useEffect` hook can download and update state when the site is loaded:
```mermaid
flowchart LR
@ -150,12 +150,13 @@ flowchart LR
wb --> |wb.Sheets\nselect sheet| ws
ws --> |sheet_to_json\n\n| aoo
aoo --> |setPres\nfrom `setState`| state
linkStyle 1,2,3 color:blue,stroke:blue;
```
<Tabs groupId="lang">
<TabItem name="JS" value="JavaScript">
```js
```js title="In a useEffect hook, update state with data from a remote workbook"
import { useEffect } from 'react';
import { read, utils } from 'xlsx';
@ -182,7 +183,7 @@ useEffect(() => { (async() => {
</TabItem>
<TabItem name="TS" value="TypeScript" default>
```ts
```ts title="In a useEffect hook, update state with data from a remote workbook"
import { useEffect } from 'react';
import { read, utils } from 'xlsx';
@ -252,9 +253,10 @@ flowchart LR
state --> |json_to_sheet\n\n| ws
ws --> |book_new\nbook_append_sheet| wb
wb --> |writeFile\n\n| file
linkStyle 0,1,2 color:blue,stroke:blue;
```
```ts
```ts title="Export data from state to a new XLSX workbook"
import { useCallback } from 'react';
import { utils, writeFile } from 'xlsx';
@ -332,7 +334,7 @@ This demo was tested in the following environments:
| ReactJS | ViteJS | Date |
|:---------|:--------|:-----------|
| `18.3.1` | `6.0.1` | 2024-12-12 |
| `19.1.0` | `6.3.5` | 2025-05-11 |
:::
@ -369,7 +371,7 @@ The generated site will be placed in the `dist` folder.
6) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -384,23 +386,14 @@ This demo was tested in the following environments:
| ReactJS | CRA | Date |
|:---------|:--------|:-----------|
| `18.2.0` | `5.0.1` | 2024-12-12 |
| `19.1.0` | `5.1.0` | 2025-05-11 |
:::
:::caution pass
CRA has known compatibility issues with React 19[^5]. CRA no longer receives
updates and the ReactJS docs no longer recommend using CRA. For new projects, it
is strongly recommended to use ViteJS with the `react` or `react-ts` templates.
:::
1) Create a new site:
```bash
npx -y create-react-app@5.0.1 --scripts-version=5.0.1 sheetjs-react
npx -y create-react-app@5.1.0 sheetjs-react
```
2) Install the SheetJS dependency and start the dev server:
@ -408,7 +401,7 @@ npx -y create-react-app@5.0.1 --scripts-version=5.0.1 sheetjs-react
<CodeBlock language="bash">{`\
cd sheetjs-react
npm i
npm i react@18.2.0 react-dom@18.2.0 web-vitals --save --save-exact
npm i react@19.1.0 react-dom@19.1.0 web-vitals --save --save-exact
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
npm start`}
</CodeBlock>
@ -431,7 +424,7 @@ The generated site will be placed in the `build` folder.
6) Start a local web server:
```bash
npx http-server build
npx -y http-server build
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -446,7 +439,7 @@ This demo was tested in the following environments:
| ReactJS | NextJS | Date |
|:---------|:---------|:-----------|
| `19.0.0` | `15.1.0` | 2024-12-13 |
| `19.1.0` | `15.3.2` | 2025-05-11 |
:::
@ -567,7 +560,7 @@ This demo was tested in the following environments:
| Preact | ViteJS | Date |
|:----------|:----------|:-----------|
| `10.22.1` | `5.3.3` | 2024-12-17 |
| `10.26.6` | `5.4.19` | 2025-05-11 |
:::
@ -578,7 +571,12 @@ npm init preact sheetjs-preact
```
This will initiate the project creation process. **Follow the on-screen prompts and
press Enter to accept the default options.**
press Enter to accept the default options:**
- `Project language:` JavaScript
- `Use router?` No
- `Prerender app (SSG)?` No
- `Use ESLint?` No
2) Install the SheetJS dependency and start the dev server:
@ -620,7 +618,7 @@ The generated site will be placed in the `dist` folder.
7) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -641,10 +639,149 @@ 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[^6] well!
HTML Tables support elements with `rowspan` and `colspan` attributes.
#### State
The state will be the serialized HTML string:
<Tabs groupId="lang">
<TabItem name="JS" value="JavaScript">
```ts
import { useState } from 'react';
/* the component state is a string */
const [__html, setHtml] = useState("");
```
</TabItem>
<TabItem name="TS" value="TypeScript" default>
```ts
import { useState } from 'react';
/* the component state is a string */
const [__html, setHtml] = useState<string>("");
```
</TabItem>
</Tabs>
:::info Use of the variable name `__html`
Examples use the name `__html` due to the design of `dangerouslySetInnerHTML`.
`dangerouslySetInnerHTML` expects objects of the form `{ __html: "html code" }`.
For example, the following snippet assumes `html` is the variable name:
```jsx
<div ref={tbl} dangerouslySetInnerHTML={{ __html: html }} />
```
By using the name `__html`, the ES6 shorthand syntax simplifies the code:
```jsx
<div ref={tbl} dangerouslySetInnerHTML={{ __html }} />
```
:::
#### Updating State
The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function
generates HTML that is aware of merges and other worksheet features. ReactJS
`dangerouslySetInnerHTML`[^7] prop allows code to set the `innerHTML` attribute,
effectively inserting the code into the page.
generates HTML that is aware of merges and other worksheet features.
A `useEffect` hook can download and update state when the site is loaded:
```mermaid
flowchart LR
url[(Remote\nFile)]
ab[(Data\nArrayBuffer)]
wb(SheetJS\nWorkbook)
ws(SheetJS\nWorksheet)
html(HTML\nTABLE)
state((component\nstate))
url --> |fetch\n\n| ab
ab --> |read\n\n| wb
wb --> |wb.Sheets\nselect sheet| ws
ws --> |sheet_to_html\n\n| html
html --> |setHtml\nfrom `setState`| state
linkStyle 1,2,3 color:blue,stroke:blue;
```
```js title="In a useEffect hook, update state with HTML generated from a remote workbook"
import { useEffect } from 'react';
import { read, utils } from 'xlsx';
/* Fetch and update the state once */
useEffect(() => { (async() => {
/* Download from https://docs.sheetjs.com/pres.numbers */
const f = await fetch("https://docs.sheetjs.com/pres.numbers");
const ab = await f.arrayBuffer();
// highlight-start
/* parse */
const wb = read(ab);
/* generate HTML TABLE from first worksheet */
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
const data = utils.sheet_to_html(ws); // generate objects
/* update state */
setHtml(data); // update state
// highlight-end
})(); }, []);
```
#### Rendering Data
ReactJS `dangerouslySetInnerHTML`[^7] prop allows code to set the `innerHTML`
attribute, effectively inserting the code into the page.
It is strongly recommended to set the `innerHTML` of a parent `DIV` container.
By attaching a `ref`, callbacks will be able to access the live `TABLE` element.
```jsx title="Example JSX for displaying HTML TABLE code"
<div ref={tbl} dangerouslySetInnerHTML={{ __html }} />
```
#### Exporting Data
The [`writeFile`](/docs/api/write-options) and [`table_to_book`](/docs/api/utilities/html#html-table-input)
functions simplify exporting data. They are best used in the function bodies of
`useCallback`[^4] hooks attached to button or other elements.
A callback can generate a local file when a user clicks a button:
```mermaid
flowchart LR
state((component\nstate))
wb(SheetJS\nWorkbook)
file[(XLSX\nexport)]
state --> |table_to_book\n\n| wb
wb --> |writeFile\n\n| file
linkStyle 0,1 color:blue,stroke:blue;
```
```ts title="Export data from HTML TABLE element to a new XLSX workbook"
import { useCallback } from 'react';
import { utils, writeFile } from 'xlsx';
/* get data from live HTML TABLE and export to XLSX */
const exportFile = useCallback(() => {
/* get live reference to HTML TABLE element */
const elt = tbl.current.getElementsByTagName("TABLE")[0];
/* generate workbook from element */
// highlight-next-line
const wb = utils.table_to_book(elt);
/* export to XLSX */
writeFile(wb, "SheetJSReactAoO.xlsx");
}, [pres]);
```
#### Complete Component
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
@ -701,7 +838,7 @@ This demo was tested in the following environments:
| ReactJS | ViteJS | Date |
|:---------|:--------|:-----------|
| `18.3.1` | `6.0.1` | 2024-12-13 |
| `19.1.0` | `6.3.5` | 2025-05-11 |
:::
@ -738,7 +875,7 @@ The generated site will be placed in the `dist` folder.
6) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -753,22 +890,14 @@ This demo was tested in the following environments:
| ReactJS | CRA | Date |
|:---------|:--------|:-----------|
| `18.2.0` | `5.0.1` | 2024-12-31 |
:::
:::caution pass
CRA has known compatibility issues with React 19[^5]. CRA no longer receives
updates and the ReactJS docs no longer recommend using CRA. For new projects, it
is strongly recommended to use ViteJS with the `react` or `react-ts` templates.
| `19.1.0` | `5.1.0` | 2025-05-11 |
:::
1) Create a new site:
```bash
npx -y create-react-app@5.0.1 --scripts-version=5.0.1 sheetjs-react
npx -y create-react-app@5.1.0 sheetjs-react
```
2) Install the SheetJS dependency and start the dev server:
@ -776,7 +905,7 @@ npx -y create-react-app@5.0.1 --scripts-version=5.0.1 sheetjs-react
<CodeBlock language="bash">{`\
cd sheetjs-react
npm i
npm i react@18.2.0 react-dom@18.2.0 web-vitals --save --save-exact
npm i react@19.1.0 react-dom@19.1.0 web-vitals --save --save-exact
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
npm start`}
</CodeBlock>
@ -799,7 +928,7 @@ The generated site will be placed in the `build` folder.
6) Start a local web server:
```bash
npx http-server build
npx -y http-server build
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -812,9 +941,9 @@ and test the page.
This demo was tested in the following environments:
| Preact | ViteJS | Date |
|:----------|:--------|:-----------|
| `10.22.1` | `5.3.3` | 2024-12-17 |
| Preact | ViteJS | Date |
|:----------|:---------|:-----------|
| `10.26.6` | `5.4.19` | 2025-05-11 |
:::
@ -823,11 +952,15 @@ npm init preact sheetjs-preact
```
This will initiate the project creation process. **Follow the on-screen prompts and
press Enter to accept the default options.**
press Enter to accept the default options:**
- `Project language:` JavaScript
- `Use router?` No
- `Prerender app (SSG)?` No
- `Use ESLint?` No
2) Install the SheetJS dependency and start the dev server:
<CodeBlock language="bash">{`\
cd sheetjs-preact
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
@ -866,7 +999,7 @@ The generated site will be placed in the `dist` folder.
7) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -913,8 +1046,8 @@ const columns = Array.from({ length: range.e.c + 1 }, (_, i) => ({
## Legacy Deployments
[The Standalone Scripts](/docs/getting-started/installation/standalone) play nice
with legacy deployments that do not use a bundler.
[SheetJS Standalone Scripts](/docs/getting-started/installation/standalone) use
simple `SCRIPT` tags and work with legacy deployments that do not use a bundler.
[The legacy demo](pathname:///react/index.html) shows a simple ReactJS component
transpiled in the browser using Babel standalone library.

@ -397,7 +397,7 @@ The generated site will be placed in the `dist` folder.
6) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -449,7 +449,7 @@ The generated site will be placed in the `dist` folder.
6) Start a local web server:
```bash
npx http-server .output/public/
npx -y http-server .output/public/
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -558,7 +558,7 @@ The generated site will be placed in the `dist` folder.
6) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -610,7 +610,7 @@ The generated site will be placed in the `dist` folder.
6) Start a local web server:
```bash
npx http-server .output/public/
npx -y http-server .output/public/
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser

@ -441,7 +441,7 @@ generated. The `dist` folder in this demo can be deployed on a static host.
9) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser
@ -611,7 +611,7 @@ generated. The `dist` folder in this demo can be deployed on a static host.
9) Start a local web server:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser

@ -173,7 +173,7 @@ npx vite build
7) Verify the new site by running a local web server in the `dist` folder:
```bash
npx http-server dist
npx -y http-server dist
```
8) Access the displayed URL (typically `http://localhost:8080`) in a web browser

@ -145,7 +145,7 @@ npx -y esbuild@0.19.8 esbrowser.js --bundle --outfile=esb.browser.js
5) Start a local HTTP server:
```bash
npx http-server .
npx -y http-server .
```
Access the displayed URL (typically `http://localhost:8080`) with a web browser.

@ -322,7 +322,7 @@ npx webpack --mode=production
6) Start a local HTTP server:
```bash
npx http-server .
npx -y http-server .
```
7) Load the displayed URL (typically `http://localhost:8080/`) in a web browser.

@ -177,7 +177,7 @@ npm install --save browserify@3.46.1
5) Start a local HTTP server:
```bash
npx http-server .
npx -y http-server .
```
6) Load the displayed URL (typically `http://localhost:8080/`) in a web browser.

@ -209,7 +209,7 @@ uses normal functions and traditional Promise chains.
3) Start a local HTTP server:
```bash
npx http-server .
npx -y http-server .
```
4) Load the displayed URL (typically `http://localhost:8080/`) in a web browser.

@ -169,7 +169,7 @@ This step will create `bundle.js`
5) Start a local HTTP server:
```bash
npx http-server .
npx -y http-server .
```
Access the displayed URL (typically `http://localhost:8080/`) in a web browser.

@ -34,8 +34,8 @@ This demo was tested in the following environments:
| Version | Date |
|:---------|:-----------|
| `2.13.3` | 2024-12-31 |
| `1.12.3` | 2024-12-31 |
| `2.14.4` | 2025-05-07 |
| `1.12.3` | 2025-05-07 |
:::
@ -239,7 +239,7 @@ The production site will be stored in the `dist` folder
7) Start a local web server and serve the `dist` folder:
```bash
npx http-server dist
npx -y http-server dist
```
Access the displayed URL (typically `http://localhost:8080/`) in a web browser.

@ -195,7 +195,7 @@ This command will create the script `lib/web.js`
6) Start a local HTTP server, then go to `http://localhost:8080/`
```bash
npx http-server .
npx -y http-server .
```
Click on "Click here to export" to generate a file.

@ -164,7 +164,7 @@ npx snowpack@3.8.8 build
5) Start a local HTTP server:
```bash
npx http-server build/
npx -y http-server build/
```
6) Open a web browser to the displayed URL (typically `http://localhost:8080/`).
@ -290,7 +290,7 @@ npx wmr@3.8.0 build
5) Start a local HTTP server:
```bash
npx http-server dist/
npx -y http-server dist/
```
6) Open a web browser to the displayed URL (typically `http://localhost:8080/`).

@ -36,12 +36,13 @@ the file can be downloaded or previewed in the browser.
This demo was tested in the following deployments:
| Platform | Version | Date |
|:-------------|:---------|:-----------|
| Chromium 131 | `1.9.0` | 2024-12-22 |
| Konqueror 22 | `1.9.0` | 2025-04-23 |
| NodeJS 20 | `1.10.0` | 2024-12-22 |
| BunJS 1.1 | `1.10.0` | 2024-12-22 |
| Platform | Version | Date |
|:--------------|:---------|:-----------|
| Chromium 136 | `1.9.0` | 2025-05-07 |
| Safari 17.5 | `1.9.0` | 2025-05-07 |
| Konqueror 22 | `1.9.0` | 2025-05-07 |
| NodeJS 24.0.0 | `1.11.0` | 2025-05-07 |
| BunJS 1.2.10 | `1.11.0` | 2025-05-07 |
:::

@ -231,7 +231,7 @@ This will create a static site in the `_site` folder
8) Test the generated site by starting a web server:
```bash
npx http-server _site
npx -y http-server _site
```
The program will display a URL (typically `http://localhost:8080`). Accessing

@ -294,7 +294,7 @@ The final script will be saved to `out.js`
7) Start a local web server to host the project folder:
```bash
npx http-server .
npx -y http-server .
```
The command will print a list of URLs.

@ -430,7 +430,7 @@ Save and refresh the page. A data table should be displayed
```bash
npm run build
npx http-server dist/
npx -y http-server dist/
```
The terminal will display a URL, typically `http://127.0.0.1:8080` . Access
@ -506,7 +506,7 @@ Save and refresh the page. A data table should be displayed
```bash
npm run build
npx http-server dist/
npx -y http-server dist/
```
The terminal will display a URL, typically `http://127.0.0.1:8080` . Access
@ -594,7 +594,7 @@ const data = utils.sheet_to_json<IPresident>(ws);
```bash
npm run build
npx http-server dist/
npx -y http-server dist/
```
The terminal will display a URL ( `http://127.0.0.1:8080` ). Access that page

@ -334,7 +334,7 @@ The final site will be placed in the `dist` folder.
12) Start a local web server to host the `dist` folder:
```bash
npx http-server dist
npx -y http-server dist
```
The command will print a list of URLs.

@ -32,6 +32,7 @@ flowchart LR
file --> |.eleventy.js\ncustom parser| buffer
buffer --> |.eleventy.js\ncustom parser| aoo
aoo --> |index.njk\ntemplate| html
linkStyle 1 color:blue,stroke:blue;
```
:::tip No Telemetry
@ -114,10 +115,11 @@ accessed using the variable `pres` in a template:
This demo was tested in the following environments:
| Eleventy | Date |
|:---------|:-----------|
| `2.0.1` | 2024-12-23 |
| `3.0.0` | 2024-12-23 |
| Eleventy | Date |
|:---------------|:-----------|
| `2.0.1` | 2025-05-07 |
| `3.0.0` | 2025-05-07 |
| `3.1.0-beta.1` | 2025-05-07 |
:::
@ -212,7 +214,7 @@ Eleventy will place the generated site in the `_site` subfolder.
9) Start a web server to host the static site:
```bash
npx http-server _site
npx -y http-server _site
```
Open a web browser and access the displayed URL ( `http://localhost:8080` ).

@ -345,7 +345,7 @@ AstroJS will place the generated site in the `dist` subfolder.
9) Start a web server to host the static site:
```bash
npx http-server dist
npx -y http-server dist
```
Open a web browser and access the displayed URL ( `http://localhost:8080` ).

@ -39,7 +39,7 @@ This demo was tested in the following deployments:
|:-------------|:---------------|:----------|:----------|:-----------|
| `darwin-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-04-21 |
| `darwin-arm` | `4.0.0-rc.6` | `22.14.0` | Compiled | 2025-04-03 |
| `win11-x64` | `4.0.0-rc.6` | `14.15.3` | Pre-built | 2024-12-19 |
| `win11-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-05-07 |
| `win11-arm` | `4.0.0-rc.6` | `22.14.0` | Compiled | 2025-02-23 |
| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-04-21 |
| `linux-arm` | `4.0.0-rc.6` | `22.13.0` | Compiled | 2025-02-15 |

@ -38,8 +38,8 @@ This demo was tested in the following deployments:
| Architecture | Version | NodeJS | Date |
|:-------------|:--------|:---------|:-----------|
| `darwin-x64` | `5.8.1` | `18.5.0` | 2025-04-21 |
| `darwin-arm` | `5.8.1` | `18.5.0` | 2025-02-13 |
| `win11-x64` | `5.8.1` | `18.5.0` | 2024-12-19 |
| `darwin-arm` | `5.8.1` | `18.5.0` | 2025-05-11 |
| `win11-x64` | `5.8.1` | `18.5.0` | 2025-05-07 |
| `win11-arm` | `5.8.1` | `18.5.0` | 2025-02-23 |
| `linux-x64` | `5.8.1` | `18.5.0` | 2025-04-21 |
| `linux-arm` | `5.8.1` | `18.5.0` | 2025-02-15 |
@ -78,7 +78,7 @@ When this demo was last tested, `pkg` failed with an error referencing `node20`:
> Error! No available node version satisfies 'node20'
```
**`pkg` does not support NodeJS 20 or 22!**
**`pkg` does not support NodeJS 20 or 22 or 24!**
The local NodeJS version must be rolled back to version 18.

@ -32,7 +32,7 @@ This demo was tested in the following deployments:
|:-------------|:--------|:----------|:-----------|
| `darwin-x64` | `2.4.4` | `23.11.0` | 2025-04-21 |
| `darwin-arm` | `2.4.4` | `22.14.0` | 2025-04-03 |
| `win11-x64` | `2.4.4` | `16.20.2` | 2024-12-19 |
| `win11-x64` | `2.4.4` | `16.20.2` | 2025-05-07 |
| `linux-x64` | `2.4.4` | `23.11.0` | 2025-04-21 |
| `linux-arm` | `2.4.4` | `23.8.0` | 2025-02-15 |
@ -136,7 +136,7 @@ workload, Python 3.11, and NASM[^2].
:::caution pass
When the demo was last tested, the build failed:
In some test runs, the build failed:
```
Not an executable Python program
@ -168,8 +168,11 @@ When the demo was last tested on Windows, the build failed:
error MSB8020: The build tools for Visual Studio 2019 (Platform Toolset = 'v142') cannot be found. To build using the v142 build tools, please install Visual Studio 2019 build tools.
```
This error was fixed by installing the `v142` build tools through the Visual
Studio installer.
This error was fixed by installing the following components from Visual Studio:
- `C++/CLI support for v142 build tools`
- `MSVC v142 - VS 2019 - C++ x64/x86 build tools`
- `MSVC v142 - VS 2019 - C++ x64/x86 Spectre-mitigated libs`
:::

@ -81,7 +81,7 @@ This demo was last tested in the following deployments:
|:-------------|:---------|:-----------|
| `darwin-x64` | `1.2.10` | 2025-04-21 |
| `darwin-arm` | `1.2.8` | 2025-04-03 |
| `win11-x64` | `1.1.40` | 2024-12-19 |
| `win11-x64` | `1.2.13` | 2025-05-07 |
| `win11-arm` | `1.2.3` | 2025-02-23 |
| `linux-x64` | `1.1.43` | 2025-01-10 |
| `linux-arm` | `1.2.2` | 2025-02-16 |

@ -228,7 +228,7 @@ order of todo items in the export matches the list displayed in the webpage.
5) Start a local web server:
```bash
npx http-server .
npx -y http-server .
```
The command will display a URL (typically `http://localhost:8080`) which can be

@ -35,7 +35,7 @@ will be available in the future.
:::note Tested Deployments
This demo was last tested on 2024-06-12.
This demo was last tested on 2025-05-11.
:::
@ -59,7 +59,8 @@ Azure Functions Core Tools (`func`) telemetry is controlled through the
<Tabs groupId="os">
<TabItem value="unix" label="Linux/MacOS">
Add the following line to `.profile`, `.bashrc` and `.zshrc`:
Add the following line to `.profile`, `.bash_profile`, `.bashrc`, `.zprofile`,
`.zshrc`, and any other configuration files:
```bash
export FUNCTIONS_CORE_TOOLS_TELEMETRY_OPTOUT=1
@ -131,7 +132,7 @@ Uploaded files can be pulled into `ArrayBuffer` objects.
This function returns a promise that resolves to an `ArrayBuffer` object:
```js
```js title="Get raw data from an uploaded file"
const { Blob } = require('buffer');
async function get_file_from_request(request, form_field_name) {
@ -158,7 +159,7 @@ 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 from
user-submitted spreadsheets:
```js
```js title="Function that reads uploaded workbooks and converts to CSV"
const { Blob } = require('buffer');
const { app } = require('@azure/functions');
const XLSX = require('xlsx');
@ -194,7 +195,7 @@ The following example generates a sample worksheet using the `aoa_to_sheet`[^6]
method, generates a sample workbook using worksheet helper methods[^7], writes
the workbook to XLSX format in a Buffer, and sends the Buffer in the response:
```js
```js title="Function that exports data and initiates a download to XLSX"
const { app } = require('@azure/functions');
const XLSX = require('xlsx');
@ -299,10 +300,20 @@ Until the bugs are resolved, JavaScript should be preferred over TypeScript.
npm start
```
7) While the server is running, open a new terminal window and make a request:
The process will display the functions and respective URLs:
```text title="Expected output"
Functions:
SheetJSAzure: [GET,POST] http://localhost:7071/api/SheetJSAzure
(access this URL)------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
7) While the server is running, open a new terminal window and make a GET
request to the URL listed in the previous step:
```bash
curl -L http://localhost:7071/api/SheetJSAzure
curl http://localhost:7071/api/SheetJSAzure
```
The terminal should display `Hello, world!`
@ -333,7 +344,7 @@ npm start
make a POST request to the dev server:
```bash
curl -LO https://docs.sheetjs.com/pres.numbers
curl -o pres.numbers https://docs.sheetjs.com/pres.numbers
curl -X POST -F "upload=@pres.numbers" http://localhost:7071/api/SheetJSAzure
```
@ -354,19 +365,20 @@ Open in Excel or another spreadsheet editor to confirm the file is valid.
15) Click "+ Create"
16) Select the following options:
16) In the "Create Function App" screen, click "Consumption" and click "Select".
- "Select a hosting option": "Consumption"
17) In the next screen, select the following options:
- Type a memorable "Function Name" ("sheetjsazure" when last tested)
- Look for the "Function App name" input field and type a memorable function
name. When this demo was last tested, the name "sheetjsazure" was chosen.
- "Operating System": "Windows"
- "Runtime stack": select `Node.js`
17) Click "Review + create", then click "Create" to create the function.
18) Click "Review + create", then click "Create" to create the function.
The page will display a status message
The page will redirect to a new page. It will display a status message:
> ... Deployment is in progress
@ -374,21 +386,19 @@ When the resources are configured, the status will change to
> Your deployment is complete
18) Click "Go to Resource".
19) Take note of the URL from the "Essentials" table.
19) Click "Go to Resource".
#### Deploy to Azure
20) Sign into Azure:
20) Sign into Azure from the command line:
```
```bash
az login
```
The login flow resumes in the browser.
21) Deploy to Azure. Replace `FUNCTION_NAME` with the name from Step 16:
21) Deploy to Azure. Replace `FUNCTION_NAME` with the name from Step 17:
```bash
func azure functionapp publish FUNCTION_NAME
@ -429,7 +439,7 @@ make a POST request to the production server. Replace `FUNCTION_URL` with the
Invoke URL from Step 21:
```bash
curl -LO https://docs.sheetjs.com/pres.numbers
curl -o pres.numbers https://docs.sheetjs.com/pres.numbers
curl -X POST -F "upload=@pres.numbers" FUNCTION_URL
```
@ -546,9 +556,9 @@ requests and 2000 write requests per month.
- "Redundancy": select LRS (Locally-redundant storage)
5) Click "Review", then click "Create" to create the storage.
5) Click "Review + create", then click "Create" to create the storage.
The page will display a status message
The page will redirect to a new page. It will display a status message:
> ... Deployment is in progress
@ -596,11 +606,64 @@ npm init -y
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @azure/storage-blob`}
</CodeBlock>
14) Copy the [`SheetJSReadFromAzure.mjs` code block](#downloading-data) and save
to `SheetJSReadFromAzure.mjs`.
14) Save the following codeblock to `SheetJSReadFromAzure.mjs`:
15) Copy the [`SheetJSWriteToAzure.mjs` code block](#uploading-data) and save
to `SheetJSWriteToAzure.mjs`.
```js title="SheetJSReadFromAzure.mjs"
import { BlobServiceClient } from "@azure/storage-blob";
import { read, utils } from "xlsx";
/* replace these constants */
// highlight-start
const connStr = "<REPLACE WITH CONNECTION STRING>";
const containerName = "<REPLACE WITH CONTAINER NAME>";
// highlight-end
/* Blob name */
const blobName = "SheetJSBloblobber.xlsx";
/* get a readable stream*/
const blobServiceClient = BlobServiceClient.fromConnectionString(connStr);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobClient = containerClient.getBlobClient(blobName);
const response = (await blobClient.download()).readableStreamBody;
/* collect data into a Buffer */
const bufs = [];
for await(const buf of response) bufs.push(buf);
const downloaded = Buffer.concat(bufs);
/* parse downloaded buffer */
const wb = read(downloaded);
/* print first worksheet */
console.log(utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
```
15) Save the following codeblock to `SheetJSWriteToAzure.mjs`:
```js title="SheetJSWriteToAzure.mjs"
import { BlobServiceClient } from "@azure/storage-blob";
import { write, utils } from "xlsx";
/* replace these constants */
// highlight-start
const connStr = "<REPLACE WITH CONNECTION STRING>";
const containerName = "<REPLACE WITH CONTAINER NAME>";
// highlight-end
/* Blob name */
const blobName = "SheetJSBloblobber.xlsx";
/* Create a simple workbook and write XLSX to buffer */
const ws = utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]);
const wb = utils.book_new(); utils.book_append_sheet(wb, ws, "Sheet1");
const buf = write(wb, {type: "buffer", bookType: "xlsx"});
/* upload buffer */
const blobServiceClient = BlobServiceClient.fromConnectionString(connStr);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const uploadBlobResponse = await blockBlobClient.upload(buf, buf.length);
```
16) Edit both `SheetJSReadFromAzure.mjs` and `SheetJSWriteToAzure.mjs`:
@ -616,7 +679,7 @@ the buffer to a file named `SheetJSBloblobber.xlsx` on Azure Blob Storage.
The read demo fetches `SheetJSBloblobber.xlsx` and displays the data.
```
```text title="Data in SheetJSBloblobber.xlsx"
| A | B | C | D | E | F | G |
---+---|---|---|---|---|---|---|
1 | S | h | e | e | t | J | S |
@ -641,7 +704,7 @@ node SheetJSReadFromAzure.mjs
It will fetch the file created in the previous step and display CSV rows.
```
```text title="Expected output"
S,h,e,e,t,J,S
5,4,3,3,7,9,5
```

@ -30,7 +30,7 @@ This demo was tested by SheetJS users in the following deployments:
| Architecture | Version | Date |
|:-------------|:--------|:-----------|
| `darwin-x64` | R2024b | 2025-03-31 |
| `win11-x64` | R2024b | 2024-12-21 |
| `win11-x64` | R2024b | 2025-05-10 |
:::
@ -234,14 +234,14 @@ run in the macOS Terminal or Windows PowerShell:
<CodeBlock language="bash">{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2
curl -LO https://docs.sheetjs.com/cli/xlsx-cli.js
curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js
npx -y nexe -t 14.15.3 xlsx-cli.js`}
</CodeBlock>
2) Download https://docs.sheetjs.com/pres.numbers to the workspace folder:
```bash
curl -LO https://docs.sheetjs.com/pres.numbers
curl -o pres.numbers https://docs.sheetjs.com/pres.numbers
```
4) Save the following to `SheetJSMATLAB.m` in the workspace folder:

@ -23,7 +23,7 @@ library to read data from spreadsheets and converts to a Maple-friendly format.
```mermaid
flowchart LR
ofile[(workbook\nXLSB file)]
ofile[(generic\nworkbook)]
nfile[(clean file\nXLSX)]
data[[Maple\nTable]]
ofile --> |Maple Extension\nSheetJS + Duktape| nfile
@ -37,7 +37,7 @@ This demo was tested by SheetJS users in the following deployments:
| Architecture | Version | Date |
|:-------------|:---------|:-----------|
| `darwin-x64` | `2024.0` | 2025-01-10 |
| `win11-x64` | `2024.0` | 2024-12-19 |
| `win11-x64` | `2024.2` | 2025-05-07 |
:::
@ -60,7 +60,7 @@ and generates clean XLSX files that Maple can import.
The extension function ultimately pairs the SheetJS `read`[^2] and `write`[^3]
methods to read data from the old file and write a new file:
```js
```js title="Script that will be run by Maple extension"
var workbook = XLSX.read(original_file_data, { type: "buffer" });
var new_file_data = XLSX.write(workbook, { type: "array", bookType: "xlsx" });
```
@ -84,6 +84,7 @@ flowchart LR
wb --> |SheetJS\n`write`| njbuf
njbuf --> |Duktape\nBuffer Ops| nbuf
nbuf --> |C\nWrite File| nfile
linkStyle 2,3 color:blue,stroke:blue;
```
### C Extensions
@ -128,7 +129,7 @@ file, exports data to `sheetjsw.xlsx` and returns the string `"sheetjsw.xlsx"`.
This can be chained with `Import` from `ExcelTools`:
```maple
```maple title="Sample usage of SheetToXLSX extension"
with(ExcelTools);
Import(SheetToXLSX("pres.numbers"))
```

@ -148,7 +148,7 @@ This demo was tested in the following deployments:
|:--------------|:-------------|:--------------|:-----------------|:-----------|
| `13.7.5` | `darwin-x64` | macOS 15.3.2 | `clang 16.0.0` | 2025-03-31 |
| `13.5.92` | `darwin-arm` | macOS 14.5 | `clang 16.0.0` | 2025-02-15 |
| `12.7.130` | `win11-x64` | Windows 11 | `CL 19.42.34435` | 2024-12-20 |
| `13.8.124` | `win11-x64` | Windows 11 | `CL 19.43.34810` | 2025-05-11 |
| `12.7.130` | `linux-x64` | HoloOS 3.6.20 | `gcc 13.2.1` | 2025-01-02 |
| `13.5.92` | `linux-arm` | Debian 12 | `gcc 12.2.0` | 2025-02-15 |
@ -204,13 +204,15 @@ installation steps.
Using the installer tool, the "Desktop development with C++" workload must be
installed. In the sidebar, verify the following components are checked:
- "C++ ATL for latest ... build tools" (`v143` when last tested)
- "C++ MFC for latest ... build tools" (`v143` when last tested)
- "C++ ATL for latest ... build tools (x86 & x64)" (`v143` when last tested)
- "C++ ATL for latest ... build tools with Spectre Mitigations (x86 & x64)" (`v143` when last tested)
- "C++ MFC for latest ... build tools (x86 & x64)" (`v143` when last tested)
- "C++ MFC for latest ... build tools with Spectre Mitigations (x86 & x64)" (`v143` when last tested)
In the "Individual components" tab, search for "Windows 11 SDK" and verify that
"Windows 11 SDK (10.0.22621.0)" is checked.
"Windows 11 SDK (10.0.26100.0)" is checked.
**Even though newer SDKs exist, Windows 11 SDK 10.0.22621.0 must be installed!**
**Even though newer SDKs may exist, V8 expects specific Windows SDK versions!**
Click "Modify" and allow the installer to finish.
@ -222,7 +224,7 @@ The SDK debugging tools must be installed after the SDK is installed.
available, search for "Installed apps".
2) When the setting panel opens, scroll down to "Windows Software Development
Kit - Windows 10.0.22621" and click "Modify".
Kit - Windows 10.0.26100" and click "Modify".
3) In the new window, select "Change" and click "Next"
@ -266,13 +268,12 @@ sudo chmod 777 /usr/local/lib
</TabItem>
<TabItem value="win" label="Windows">
[The bundle](https://storage.googleapis.com/chrome-infra/depot_tools.zip) is a
ZIP file that should be downloaded and extracted.
The demo was last tested on a NTFS-formatted drive (mounted at `C:\`). The ZIP
was extracted to `C:\src\depot_tools`.
After extracting, verify that the `depot_tools` folder is not read-only.
```bash
cd c:\
mkdir src
cd src
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
```
</TabItem>
</Tabs>
@ -334,7 +335,22 @@ gclient
gclient
```
:::caution pass
:::info Troubleshooting
In test runs on fresh machines, `gclient` failed with the following message:
```
Error: client not configured; see 'gclient config'
```
This was fixed by setting `user.name` and `user.email` in the Git configuration:
```bash
git config --global user.name "John Doe"
git config --global user.email "jdoe@email.com"
```
---
`gclient` may throw errors related to `git` and permissions issues:
@ -349,9 +365,7 @@ To add an exception for this directory, call:
These issues are related to the exFAT file system. They were resolved by running
the recommended commands and re-running `gclient`.
:::
:::caution pass
---
There may be errors pertaining to `gitconfig`:
@ -435,11 +449,11 @@ The recommended fix is to delete the referenced folder and re-run `gclient sync`
</Tabs>
5) Checkout the desired version. The following command pulls `13.7.5`:
5) Checkout the desired version. The following command pulls `13.8.124`:
```bash
git checkout tags/13.7.5 -b sample
git checkout tags/13.8.124 -b sample
```
:::caution pass
@ -447,14 +461,14 @@ git checkout tags/13.7.5 -b sample
The official documentation recommends:
```bash
git checkout refs/tags/13.7.5 -b sample -t
git checkout refs/tags/13.8.124 -b sample -t
```
This command failed in local testing:
```
E:\v8\v8>git checkout refs/tags/13.7.5 -b sample -t
fatal: cannot set up tracking information; starting point 'refs/tags/13.7.5' is not a branch
E:\v8\v8>git checkout refs/tags/13.8.124 -b sample -t
fatal: cannot set up tracking information; starting point 'refs/tags/13.8.124' is not a branch
```
:::
@ -643,6 +657,24 @@ python3 tools\dev\v8gen.py -vv x64.release.sample
ninja -C out.gn\x64.release.sample v8_monolith
```
:::info pass
If the expected Windows SDK version is missing or the debugging tools are not
installed, the build will fail with an error referencing `include`:
```
Exception: Path "C:\Program Files (x86)\Windows Kits\10\\include\10.0.26100.0\\um" from environment variable "include" does not exist. Make sure the necessary SDK is installed.
```
In the error message, the expected Windows SDK version is listed in the path.
For example, in the aforementioned message, `10.0.26100.0` is the SDK version.
The expected version of the Windows SDK should be installed from Visual Studio
Installer. After installing the SDK, the corresponding SDK debugging tools
should be installed using the procedure from Step 0.
:::
:::caution pass
In local testing, the build sometimes failed with a `dbghelp.dll` error:
@ -744,7 +776,7 @@ ld: multiple errors: unknown file type in '/Users/sheetjs/dev/v8/v8/out.gn/x64.r
```bash
g++ -I. -Iinclude samples/hello-world.cc -o hello_world -fno-rtti -lv8_monolith \
-lv8_libbase -lv8_libplatform -ldl -Lout.gn/x64.release.sample/obj/ -pthread \
-std=c++17 -DV8_COMPRESS_POINTERS=1 -DV8_ENABLE_SANDBOX
-std=c++20 -DV8_COMPRESS_POINTERS=1 -DV8_ENABLE_SANDBOX
./hello_world
```
@ -762,10 +794,32 @@ g++ -I. -Iinclude samples/hello-world.cc -o hello_world -fno-rtti -lv8_monolith
<TabItem value="win11-x64" label="Windows">
```bash
cl /I. /Iinclude samples/hello-world.cc /GR- v8_monolith.lib Advapi32.lib Winmm.lib Dbghelp.lib /std:c++17 /DV8_COMPRESS_POINTERS=1 /DV8_ENABLE_SANDBOX /link /out:hello_world.exe /LIBPATH:out.gn\x64.release.sample\obj\
cl /I. /Iinclude samples/hello-world.cc /GR- v8_monolith.lib Advapi32.lib Winmm.lib Dbghelp.lib /std:c++20 /DV8_COMPRESS_POINTERS=1 /DV8_ENABLE_SANDBOX /link /out:hello_world.exe /LIBPATH:out.gn\x64.release.sample\obj\
.\hello_world.exe
```
:::caution pass
When this demo was last tested, the build failed with a `C++` standard error:
```
c:\v8\v8\include\v8config.h(13): fatal error C1189: #error: "C++20 or later required."
```
The `/std:c++20` option sets the `C++` standard in use. The workaround is to
suppress the broken version check:
```c++ title="include\v8config.h (edit highlighted line)"
#if __cplusplus <= 201703L
// highlight-next-line
//#error "C++20 or later required."
#endif
```
After suppressing the error, re-run the build commands.
:::
</TabItem>
</Tabs>
@ -901,7 +955,7 @@ g++ -I. -Iinclude hello-world.cc -o hello_world -fno-rtti -lv8_monolith \
<TabItem value="win" label="Windows">
```bash
cl /MT /I..\v8\v8\ /I..\v8\v8\include hello-world.cc /GR- v8_monolith.lib Advapi32.lib Winmm.lib Dbghelp.lib /std:c++17 /DV8_COMPRESS_POINTERS=1 /DV8_ENABLE_SANDBOX /link /out:hello_world.exe /LIBPATH:..\v8\v8\out.gn\x64.release.sample\obj\
cl /MT /I..\v8\v8\ /I..\v8\v8\include hello-world.cc /GR- v8_monolith.lib Advapi32.lib Winmm.lib Dbghelp.lib /std:c++20 /DV8_COMPRESS_POINTERS=1 /DV8_ENABLE_SANDBOX /link /out:hello_world.exe /LIBPATH:..\v8\v8\out.gn\x64.release.sample\obj\
.\hello_world.exe
```
@ -974,7 +1028,7 @@ g++ -I. -Iinclude sheetjs.v8.cc -o sheetjs.v8 -fno-rtti -lv8_monolith \
<TabItem value="win" label="Windows">
```bash
cl /MT /I..\v8\v8\ /I..\v8\v8\include sheetjs.v8.cc /GR- v8_monolith.lib Advapi32.lib Winmm.lib Dbghelp.lib /std:c++17 /DV8_COMPRESS_POINTERS=1 /DV8_ENABLE_SANDBOX /link /out:sheetjs.v8.exe /LIBPATH:..\v8\v8\out.gn\x64.release.sample\obj\
cl /MT /I..\v8\v8\ /I..\v8\v8\include sheetjs.v8.cc /GR- v8_monolith.lib Advapi32.lib Winmm.lib Dbghelp.lib /std:c++20 /DV8_COMPRESS_POINTERS=1 /DV8_ENABLE_SANDBOX /link /out:sheetjs.v8.exe /LIBPATH:..\v8\v8\out.gn\x64.release.sample\obj\
```
</TabItem>
@ -1036,7 +1090,7 @@ This demo was last tested in the following deployments:
|:-------------|:----------|:-----------|
| `darwin-x64` | `136.0.0` | 2025-04-21 |
| `darwin-arm` | `134.3.0` | 2025-02-13 |
| `win11-x64` | `130.0.2` | 2024-12-20 |
| `win11-x64` | `137.1.0` | 2025-05-11 |
| `linux-x64` | `130.0.7` | 2025-01-09 |
| `linux-arm` | `134.4.0` | 2025-02-15 |
@ -1070,12 +1124,45 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://docs.sheetjs.com/pres.numbers`}
</CodeBlock>
:::note pass
In PowerShell, the command may fail with a parameter error:
```
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
```
`curl.exe` must be invoked directly:
<CodeBlock language="bash">{`\
curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl.exe -LO https://docs.sheetjs.com/pres.numbers`}
</CodeBlock>
:::
4) Download [`main.rs`](pathname:///v8/main.rs) and replace `src/main.rs`:
```bash
curl -L -o src/main.rs https://docs.sheetjs.com/v8/main.rs
```
:::note pass
In PowerShell, the command may fail with a parameter error:
```
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
```
`curl.exe` must be invoked directly:
```bash
curl.exe -L -o src/main.rs https://docs.sheetjs.com/v8/main.rs
```
:::
:::info pass
There was a breaking change in version `0.102.0` affecting `v8::Context::new`.
@ -1119,7 +1206,7 @@ This demo was last tested in the following deployments:
|:-------------|:--------------|:--------|:----------|:-----------|
| `darwin-x64` | `13.2.152.16` | `4.1.1` | `24.0.1` | 2025-04-21 |
| `darwin-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2025-03-30 |
| `win11-x64` | `12.6.228.13` | `3.1.3` | `21.0.5` | 2024-12-20 |
| `win11-x64` | `13.2.152.16` | `4.1.1` | `17.0.13` | 2025-05-11 |
| `linux-x64` | `13.2.152.16` | `4.1.1` | `21.0.6` | 2025-04-21 |
| `linux-arm` | `13.2.152.16` | `4.1.1` | `17.0.14` | 2025-02-16 |
@ -1176,9 +1263,27 @@ curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet-v8-linux-arm64/4
<TabItem value="win" label="Windows">
```bash
curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet/3.1.3/javet-3.1.3.jar
curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet/4.1.1/javet-4.1.1.jar
curl -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet-v8-windows-x86_64/4.1.1/javet-v8-windows-x86_64-4.1.1.jar
```
:::note pass
In PowerShell, the command may fail with a parameter error:
```
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
```
`curl.exe` must be invoked directly:
```bash
curl.exe -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet/4.1.1/javet-4.1.1.jar
curl.exe -LO https://repo1.maven.org/maven2/com/caoccao/javet/javet-v8-windows-x86_64/4.1.1/javet-v8-windows-x86_64-4.1.1.jar
```
:::
</TabItem>
</Tabs>
@ -1195,12 +1300,45 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://docs.sheetjs.com/pres.xlsx`}
</CodeBlock>
:::note pass
In PowerShell, the command may fail with a parameter error:
```
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
```
`curl.exe` must be invoked directly:
<CodeBlock language="bash">{`\
curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl.exe -LO https://docs.sheetjs.com/pres.xlsx`}
</CodeBlock>
:::
4) Download [`SheetJSJavet.java`](pathname:///v8/SheetJSJavet.java):
```bash
curl -LO https://docs.sheetjs.com/v8/SheetJSJavet.java
```
:::note pass
In PowerShell, the command may fail with a parameter error:
```
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
```
`curl.exe` must be invoked directly:
```bash
curl.exe -LO https://docs.sheetjs.com/v8/SheetJSJavet.java
```
:::
5) Build and run the Java application:
<Tabs groupId="os">
@ -1245,8 +1383,8 @@ java -cp ".:javet-4.1.1.jar:javet-v8-linux-arm64-4.1.1.jar" SheetJSJavet pres.xl
<TabItem value="win" label="Windows">
```bash
javac -cp ".;javet-3.1.3.jar" SheetJSJavet.java
java -cp ".;javet-3.1.3.jar" SheetJSJavet pres.xlsx
javac -cp ".;javet-4.1.1.jar;javet-v8-windows-x86_64-4.1.1.jar" SheetJSJavet.java
java -cp ".;javet-4.1.1.jar;javet-v8-windows-x86_64-4.1.1.jar" SheetJSJavet pres.xlsx
```
</TabItem>
@ -1282,7 +1420,7 @@ This demo was last tested in the following deployments:
|:-------------|:--------------|:-----------|
| `darwin-x64` | `13.3.415.23` | 2025-03-31 |
| `darwin-arm` | `13.3.415.23` | 2025-03-31 |
| `win11-x64` | `12.3.219.12` | 2024-12-20 |
| `win11-x64` | `13.3.415.23` | 2025-05-11 |
| `win11-arm` | `12.3.219.12` | 2025-02-23 |
| `linux-x64` | `12.3.219.12` | 2025-01-10 |
| `linux-arm` | `12.3.219.12` | 2025-02-16 |
@ -1376,6 +1514,23 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://docs.sheetjs.com/pres.xlsx`}
</CodeBlock>
:::note pass
In PowerShell, the command may fail with a parameter error:
```
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
```
`curl.exe` must be invoked directly:
<CodeBlock language="bash">{`\
curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl.exe -LO https://docs.sheetjs.com/pres.xlsx`}
</CodeBlock>
:::
6) Replace `Program.cs` with the following:
```csharp title="Program.cs"
@ -1595,7 +1750,7 @@ This demo was last tested in the following deployments:
|:-------------|:--------------|:----------|:-----------|
| `darwin-x64` | `13.5.212.10` | `136.0.0` | 2025-04-21 |
| `darwin-arm` | `13.5.212.10` | `136.0.0` | 2025-04-24 |
| `win11-x64` | `12.6.228.3` | `0.92.0` | 2024-12-20 |
| `win11-x64` | `13.5.212.10` | `136.0.0` | 2025-05-11 |
| `linux-x64` | `12.6.228.3` | `0.92.0` | 2025-01-02 |
| `linux-arm` | `13.4.114.9` | `134.4.0` | 2025-02-15 |

@ -381,26 +381,26 @@ The ["Windows Example"](#windows-example) covers `hermes-windows`.
:::
0) Install [dependencies](https://hermesengine.dev/docs/building-and-running/#dependencies)
0) Install [dependencies](https://github.com/facebook/hermes/blob/eda3c083a57e9aa3b5b04df12ef8588b2961c02e/doc/BuildingAndRunning.md#dependencies)
<details>
<summary><b>Installation Notes</b> (click to show)</summary>
The official guidance[^6] has been verified in macOS and HoloOS (Linux).
On macOS:
On macOS, the Xcode command-line tools ship with `git`. The other dependencies
should be installed with `brew`:
```bash
brew install icu4c cmake ninja
```
On HoloOS (and other Arch Linux distros):
On HoloOS (and other Arch Linux distros), the dependencies must be installed
from the root user (using `sudo`):
```bash
sudo pacman -Syu cmake git ninja icu python zip readline
```
On Debian and Ubuntu:
On Debian and Ubuntu, `python-is-python3` should be installed:
```bash
sudo apt install cmake git ninja-build libicu-dev python3 python-is-python3 zip libreadline-dev
@ -408,7 +408,7 @@ sudo apt install cmake git ninja-build libicu-dev python3 python-is-python3 zip
:::note pass
When using virtual machines, Linux builds require at least 8 GB memory.
Linux builds require at least 8 GB memory.
:::
@ -978,6 +978,5 @@ If successful, the script will print CSV data from the test file.
[^3]: See ["Workbook Object"](/docs/csf/book)
[^4]: See [`sheet_to_csv` in "Utilities"](/docs/api/utilities/csv#csv-output)
[^5]: See [`microsoft/hermes-windows`](https://github.com/microsoft/hermes-windows) on GitHub
[^6]: See ["Dependencies" in "Building and Running"](https://hermesengine.dev/docs/building-and-running/#dependencies) in the Hermes Documentation. If this page redirects to the source repo, [see the following `archive.org` snapshot.](https://web.archive.org/web/20240103234151/http://hermesengine.dev/docs/building-and-running/)
[^7]: See ["Download Python"](https://www.python.org/downloads/) in the Python website. When the demo was last tested, Python 3.11.9 was installed.
[^8]: See [the Visual Studio website](https://visualstudio.microsoft.com/#vs-section) for download links.

@ -1,4 +1,4 @@
{
"label": "Other Languages",
"label": "JavaScript Engines",
"position": 42
}

@ -39,7 +39,7 @@ It is strongly recommended to create a separate page listing all embedded open
source software. The "open source disclosure" should be linked from relevant
pages including Terms of Service (ToS) and End User License Agreement (EULA)
[Office 365](https://web.archive.org/web/20240412032204/https://tasks.office.com/license.html)
[Office 365](https://web.archive.org/web/20250511192103/https://tasks.office.com/license.html)
includes the short-form attribution in a special license page.
<details>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 12 KiB

@ -83,11 +83,11 @@ app.listen(7262, async() => {
});
EOF
npm i --save puppeteer express
npm i --save puppeteer express@4
node -e 'var pjson = JSON.parse(fs.readFileSync("./package.json")); console.log(pjson); delete pjson.main; fs.writeFileSync("package.json", JSON.stringify(pjson))'
for n in 1.12.3 2.13.3; do
for n in 2.14.4 1.12.3; do
npm i --save parcel@$n
npx -y parcel@$n build index.html
node test.js

@ -13,7 +13,7 @@ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz exit-on-epipe c
## NOTE: must downgrade to node 18
npx -y pkg xlsx-cli.js
npx -y pkg -t 'node18-win-arm64,node18-linux-arm64,node18-macos-arm64' xlsx-cli.js
## NOTE: these steps are for darwin

17
tests/email/pst.sh Executable file

@ -0,0 +1,17 @@
#!/bin/bash
# https://docs.sheetjs.com/docs/demos/net/email/pst
cd /tmp
rm -rf sheetjs-pst
mkdir sheetjs-pst
cd sheetjs-pst
npm init -y
curl -LO https://docs.sheetjs.com/pst/SheetJSPST.js
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz pst-extractor@1.11.0
node --version
node SheetJSPST.js
bun --version
bun SheetJSPST.js

@ -13,7 +13,7 @@ curl -Lo _data/pres.xlsx https://docs.sheetjs.com/pres.xlsx
curl -L -o .eleventy.js https://docs.sheetjs.com/eleventy/_eleventy.js
curl -LO https://docs.sheetjs.com/eleventy/index.njk
for n in 2.0.1 3.0.0; do
for n in 2.0.1 3.0.0 3.1.0-beta.1; do
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @11ty/eleventy@$n
npx @11ty/eleventy@$n