forked from sheetjs/docs.sheetjs.com
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
d77a40c6bf | |||
9af5473755 | |||
1f87dda979 | |||
1b242c12ef |
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,4 +4,5 @@ package-lock.json
|
||||
pnpm-lock.yaml
|
||||
/docs
|
||||
node_modules
|
||||
.idea
|
||||
.idea
|
||||
.vscode
|
@ -352,7 +352,7 @@
|
||||
<Cell><Data ss:Type="String">Python</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
|
@ -118,20 +118,20 @@ importScripts("https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.mi
|
||||
|
||||
### Type Checker
|
||||
|
||||
:::danger VSCode Telemetry and Data Exfiltration
|
||||
:::danger VS Code Telemetry and Data Exfiltration
|
||||
|
||||
The official Microsoft builds of Visual Studio Code ("VSCode") embed telemetry
|
||||
and send information to external servers.
|
||||
The official builds of Visual Studio Code ("VS Code" or "VSCode") embed
|
||||
telemetry and send information to Microsoft servers.
|
||||
|
||||
**[VSCodium](https://vscodium.com/) is a telemetry-free fork of VSCode.**
|
||||
**[VSCodium](https://vscodium.com/) is a telemetry-free fork of VS Code.**
|
||||
|
||||
When writing code that may process personally identifiable information (PII),
|
||||
the SheetJS team strongly encourages building VSCode from source or using IDEs
|
||||
the SheetJS team strongly encourages building VS Code from source or using IDEs
|
||||
that do not exfiltrate data.
|
||||
|
||||
:::
|
||||
|
||||
The type checker integrated in VSCodium and VSCode does not currently provide
|
||||
The type checker integrated in VSCodium and VS Code does not currently provide
|
||||
type hints when using the standalone build. Using the JSDoc `@type` directive
|
||||
coupled with type imports, VSCodium will recognize the types:
|
||||
|
||||
@ -176,7 +176,7 @@ The `.d.ts` file extension must be omitted.
|
||||
|
||||
JSDoc types using the `@import` directive are not supported in `<script>` tags.
|
||||
|
||||
**This is a known bug with VSCode!**
|
||||
**This is a known bug with VS Code!**
|
||||
|
||||
:::
|
||||
|
||||
|
@ -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]}));
|
||||
|
@ -35,6 +35,7 @@ This demo was tested in the following configurations:
|
||||
|
||||
| Platform | Architecture | Date |
|
||||
|:------------------------------------------------------------------|:-------------|:-----------|
|
||||
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-05-17 |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-04-17 |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-01-28 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-01-12 |
|
||||
|
@ -42,7 +42,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:----------------|:-------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 2.2.3 | 3.13.1 | 2025-03-31 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.2 | 2025-03-30 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 2.2.3 | 3.11.8 | 2024-12-21 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 2.2.3 | 3.11.9 | 2025-04-28 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 2.2.3 | 3.13.2 | 2025-02-23 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 1.5.3 | 3.11.7 | 2025-01-01 |
|
||||
| `linux-arm` | Duktape `2.7.0` | 1.5.3 | 3.11.2 | 2025-02-16 |
|
||||
@ -203,7 +203,7 @@ DataFrame. The DataFrame will be exported to the binary XLSB spreadsheet format.
|
||||
:::note pass
|
||||
|
||||
The Windows build requires Visual Studio with "Desktop development with C++".
|
||||
Commands must be run in a "Native Tools Command Prompt" session.
|
||||
**Commands must be run in a "Native Tools Command Prompt" session.**
|
||||
|
||||
:::
|
||||
|
||||
@ -215,6 +215,14 @@ python3 -m pip install pandas
|
||||
|
||||
:::info pass
|
||||
|
||||
On Windows, Python may be available as `python.exe`:
|
||||
|
||||
```bash
|
||||
python.exe -m pip install pandas
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
On macOS and Linux, the install command may require root access:
|
||||
|
||||
```bash
|
||||
@ -305,15 +313,13 @@ cd ..
|
||||
</TabItem>
|
||||
<TabItem value="win11-x64" label="Windows">
|
||||
|
||||
- Download and extract the source tarball. Commands must be run in WSL `bash`:
|
||||
- Download and extract the source tarball:
|
||||
|
||||
```bash
|
||||
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
|
||||
tar -xJf duktape-2.7.0.tar.xz
|
||||
```
|
||||
|
||||
(Run `bash`, then run the aforementioned commands, then run `exit` to exit WSL)
|
||||
|
||||
- Enter the source folder:
|
||||
|
||||
```bash
|
||||
@ -472,6 +478,17 @@ def eval_file(ctx, path):
|
||||
python3 SheetJSPandas.py pres.numbers
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
On Windows, Python may be available as `python.exe`:
|
||||
|
||||
```bash
|
||||
python.exe SheetJSPandas.py pres.numbers
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
|
||||
If successful, the script will display DataFrame metadata:
|
||||
|
||||
```
|
||||
@ -529,7 +546,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:----------------|:--------|:-------|:-----------|
|
||||
| `darwin-x64` | Duktape `2.7.0` | 1.26.0 | 3.13.1 | 2025-03-31 |
|
||||
| `darwin-arm` | Duktape `2.7.0` | 1.26.0 | 3.13.2 | 2025-03-30 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 1.17.1 | 3.11.8 | 2024-12-21 |
|
||||
| `win11-x64` | Duktape `2.7.0` | 1.28.1 | 3.11.9 | 2025-04-28 |
|
||||
| `win11-arm` | Duktape `2.7.0` | 1.23.0 | 3.13.2 | 2025-02-23 |
|
||||
| `linux-x64` | Duktape `2.7.0` | 1.18.0 | 3.11.7 | 2025-01-01 |
|
||||
| `linux-arm` | Duktape `2.7.0` | 1.22.0 | 3.11.2 | 2025-02-16 |
|
||||
@ -599,10 +616,18 @@ python3 -m pip install polars
|
||||
|
||||
:::info pass
|
||||
|
||||
On Windows, Python may be available as `python.exe`:
|
||||
|
||||
```bash
|
||||
python.exe -m pip install polars
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
On macOS and Linux, the install command may require root access:
|
||||
|
||||
```bash
|
||||
sudo python3 -m pip install pandas
|
||||
sudo python3 -m pip install polars
|
||||
```
|
||||
|
||||
:::
|
||||
@ -662,6 +687,16 @@ cp ../libduktape.* ../SheetJSPandas.py ../sheetjs.py ../*.js ../*.numbers .
|
||||
python3 SheetJSPandas.py pres.numbers
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
On Windows, Python may be available as `python.exe`:
|
||||
|
||||
```bash
|
||||
python.exe SheetJSPandas.py pres.numbers
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::note pass
|
||||
|
||||
If the virtual environment was configured in the previous step, run:
|
||||
@ -692,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
|
||||
|
@ -91,7 +91,7 @@ in the ["API Reference"](/docs/api/) section of the documentation.
|
||||
|
||||
<!-- The SheetJS Standalone script must be loaded before the UI5 bootstrap -->
|
||||
<script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script>
|
||||
|
||||
|
||||
<!-- UI5 bootstrap script -->
|
||||
<script
|
||||
id="sap-ui-bootstrap"
|
||||
@ -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 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -377,7 +377,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:-------|:-----------|
|
||||
| `darwin-x64` | 0.1.48 | 2.2.6 | 2025-03-31 |
|
||||
| `darwin-arm` | 0.1.48 | 2.2.12 | 2025-04-24 |
|
||||
| `win11-x64` | 0.1.48 | 2.0.4 | 2024-10-30 |
|
||||
| `win11-x64` | 0.1.48 | 2.2.12 | 2025-04-28 |
|
||||
| `win11-arm` | 0.1.48 | 2.2.1 | 2025-02-23 |
|
||||
| `linux-x64` | 0.1.48 | 2.0.5 | 2025-01-10 |
|
||||
| `linux-arm` | 0.1.48 | 2.1.10 | 2025-02-16 |
|
||||
@ -392,17 +392,17 @@ This demo was tested in the following deployments:
|
||||
2) Run the script with `--allow-net` and `--allow-write` entitlements:
|
||||
|
||||
```bash
|
||||
deno run --allow-net --allow-write SheetJSDenoDOM.ts
|
||||
deno run --allow-net --allow-write --allow-import SheetJSDenoDOM.ts
|
||||
```
|
||||
|
||||
The script will create a file `SheetJSDenoDOM.xlsx` that can be opened.
|
||||
|
||||
:::caution pass
|
||||
:::note pass
|
||||
|
||||
Deno 2 additionally requires the `--allow-import` entitlement:
|
||||
In older versions of Deno, the `--allow-import` flag must be omitted:
|
||||
|
||||
```bash
|
||||
deno run --allow-net --allow-write --allow-import SheetJSDenoDOM.ts
|
||||
deno run --allow-net --allow-write SheetJSDenoDOM.ts
|
||||
```
|
||||
|
||||
:::
|
||||
|
@ -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` ).
|
||||
|
@ -49,7 +49,8 @@ This demo was tested in the following environments:
|
||||
| Nuxt Content | Nuxt | Date |
|
||||
|:-------------|:-----------|:-----------|
|
||||
| `1.15.1` | `2.18.1` | 2025-04-23 |
|
||||
| `2.13.4` | `3.14.159` | 2024-11-14 |
|
||||
| `2.13.4` | `3.17.2` | 2025-05-12 |
|
||||
| `3.5.1` | `3.17.3` | 2025-05-18 |
|
||||
|
||||
:::
|
||||
|
||||
@ -525,8 +526,8 @@ script files. The module script is expected to export a module configured with
|
||||
- Add the transformer to Nuxt Content in the `content:context` hook
|
||||
|
||||
```js title="sheetmodule.ts (Module)"
|
||||
import { resolve } from 'path'
|
||||
import { defineNuxtModule } from '@nuxt/kit'
|
||||
import { resolve } from 'path';
|
||||
import { defineNuxtModule } from '@nuxt/kit';
|
||||
|
||||
export default defineNuxtModule({
|
||||
/* module setup method */
|
||||
@ -549,7 +550,7 @@ The module must be loaded in `nuxt.config.ts` and added to the `modules` array:
|
||||
|
||||
```ts title="nuxt.config.ts"
|
||||
// highlight-next-line
|
||||
import SheetJSModule from './sheetmodule'
|
||||
import SheetJSModule from './sheetmodule';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
// @ts-ignore
|
||||
@ -606,7 +607,7 @@ from the script setup will be shaped like the return value from the transformer.
|
||||
:::caution pass
|
||||
|
||||
For some older versions, parts of the Nuxt dependency tree did not support
|
||||
NodeJS version 20. If the `yarn install` step fails with a message like
|
||||
NodeJS version 20. If the `pnpm install` step fails with a message like
|
||||
|
||||
```
|
||||
error @nuxt/kit@3.4.1: The engine "node" is incompatible with this module.
|
||||
@ -619,17 +620,18 @@ The recommended solution is to switch to Node 18.
|
||||
1) Create a stock app and install dependencies:
|
||||
|
||||
```bash
|
||||
npx -y nuxi init -t content --packageManager yarn --no-gitInit sheetjs-nc2
|
||||
npx -y nuxi init -t content --packageManager pnpm --no-gitInit sheetjs-nc2 -M ,
|
||||
cd sheetjs-nc2
|
||||
npx -y yarn install
|
||||
npx -y yarn add --dev @types/node
|
||||
npx -y pnpm install
|
||||
npx -y pnpm install @nuxt/content@2 --save
|
||||
npx -y pnpm install @types/node @nuxt/kit --save
|
||||
```
|
||||
|
||||
2) Install the SheetJS library and start the server:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npx -y yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
npx -y yarn dev`}
|
||||
npx -y pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
npx -y pnpm dev`}
|
||||
</CodeBlock>
|
||||
|
||||
|
||||
@ -639,7 +641,7 @@ When the build finishes, the terminal will display a URL like:
|
||||
> Local: http://localhost:3000/
|
||||
```
|
||||
|
||||
The server is listening on that URL. Open the link in a web browser.
|
||||
The server is listening on that URL. Open the link in a web browser.
|
||||
|
||||
3) Download https://docs.sheetjs.com/pres.xlsx and move to the `content` folder.
|
||||
|
||||
@ -649,12 +651,12 @@ curl -L -o content/pres.xlsx https://docs.sheetjs.com/pres.xlsx
|
||||
|
||||
4) Create the transformer. Two files must be saved at the root of the project:
|
||||
|
||||
- [`sheetformer.ts`](https://docs.sheetjs.com/nuxt/3/sheetformer.ts) (raw transformer module)
|
||||
- [`sheetformer.ts`](https://docs.sheetjs.com/nuxt/2/sheetformer.ts) (raw transformer module)
|
||||
- [`sheetmodule.ts`](https://docs.sheetjs.com/nuxt/3/sheetmodule.ts) (Nuxt configuration module)
|
||||
|
||||
```bash
|
||||
curl -O https://docs.sheetjs.com/nuxt/3/sheetformer.ts
|
||||
curl -O https://docs.sheetjs.com/nuxt/3/sheetmodule.ts
|
||||
curl -O https://docs.sheetjs.com/nuxt/2/sheetformer.ts
|
||||
curl -O https://docs.sheetjs.com/nuxt/2/sheetmodule.ts
|
||||
```
|
||||
|
||||
After creating the source files, the module must be added to `nuxt.config.ts`:
|
||||
@ -668,14 +670,13 @@ export default defineNuxtConfig({
|
||||
// @ts-ignore
|
||||
telemetry: false,
|
||||
// highlight-end
|
||||
devtools: { enabled: true },
|
||||
// highlight-start
|
||||
modules: [
|
||||
// highlight-next-line
|
||||
SheetJSModule,
|
||||
'@nuxt/content'
|
||||
],
|
||||
content: {}
|
||||
// highlight-end
|
||||
devtools: { enabled: true },
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
@ -684,33 +685,13 @@ Stop the dev server (<kbd>CTRL</kbd>+<kbd>C</kbd>) and run the following:
|
||||
```bash
|
||||
npx -y nuxi clean
|
||||
npx -y nuxi cleanup
|
||||
npx -y nuxi typecheck
|
||||
npx -y yarn run dev
|
||||
npx -y pnpm run dev
|
||||
```
|
||||
|
||||
Loading `http://localhost:3000/pres` should show some JSON data:
|
||||
|
||||
```json
|
||||
{
|
||||
// ...
|
||||
"data": {
|
||||
"_path": "/pres",
|
||||
// ...
|
||||
"_id": "content:pres.xlsx",
|
||||
"body": [
|
||||
{
|
||||
"name": "Sheet1", // <-- sheet name
|
||||
"data": [ // <-- array of data objects
|
||||
{
|
||||
"Name": "Bill Clinton",
|
||||
"Index": 42
|
||||
},
|
||||
```
|
||||
|
||||
5) Download [`pres.vue`](pathname:///nuxt/3/pres.vue) and save to `pages`:
|
||||
5) Download [`pres.vue`](pathname:///nuxt/2/pres.vue) and save to `app/pages`:
|
||||
|
||||
```bash
|
||||
curl -o pages/pres.vue https://docs.sheetjs.com/nuxt/3/pres.vue
|
||||
curl -o app/pages/pres.vue https://docs.sheetjs.com/nuxt/2/pres.vue
|
||||
```
|
||||
|
||||
Stop the dev server (<kbd>CTRL</kbd>+<kbd>C</kbd>) and run the following:
|
||||
@ -718,24 +699,247 @@ Stop the dev server (<kbd>CTRL</kbd>+<kbd>C</kbd>) and run the following:
|
||||
```bash
|
||||
npx -y nuxi clean
|
||||
npx -y nuxi cleanup
|
||||
npx -y yarn run dev
|
||||
npx -y pnpm run dev
|
||||
```
|
||||
|
||||
The browser should now display an HTML table.
|
||||
6) From the browser window in step 2, access `/pres` from the site. For example,
|
||||
if the URL in step 2 was `http://localhost:3000/`, the new page should be
|
||||
`http://localhost:3000/pres`.
|
||||
|
||||
6) To verify that hot loading works, open `pres.xlsx` from the `content` folder
|
||||
This page should now display an HTML table.
|
||||
|
||||
7) To verify that hot loading works, open `pres.xlsx` from the `content` folder
|
||||
with a spreadsheet editor.
|
||||
|
||||
Set cell `A7` to "SheetJS Dev" and set `B7` to `47`. Save the spreadsheet.
|
||||
|
||||
The page should automatically refresh with the new content.
|
||||
|
||||
8) Stop the server (press <kbd>CTRL</kbd>+<kbd>C</kbd> in the terminal window).
|
||||
|
||||
9) Copy `app/pages/pres.vue` to `app/pages/index.vue`:
|
||||
|
||||
```bash
|
||||
cp app/pages/pres.vue app/pages/index.vue
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
In older test runs, the Nuxt starter created a default `/` page. The most recent
|
||||
test did not create the index page, resulting in build errors. This step ensures
|
||||
some sort of index page exists.
|
||||
|
||||
:::
|
||||
|
||||
10) Build the static site:
|
||||
|
||||
```bash
|
||||
npx -y pnpm run generate
|
||||
```
|
||||
|
||||
This will create a static site in `.output/public`, which can be served with:
|
||||
|
||||
```bash
|
||||
npx -y http-server .output/public
|
||||
```
|
||||
|
||||
Access the displayed URL (typically `http://localhost:8080`) in a web browser.
|
||||
|
||||
To confirm that the spreadsheet data is added to the site, view the page source.
|
||||
|
||||
Searching for `Bill Clinton` reveals the following encoded HTML row:
|
||||
|
||||
```html
|
||||
<tr><td>Bill Clinton</td><td>42</td></tr>
|
||||
```
|
||||
|
||||
## Nuxt Content v3
|
||||
|
||||
:::danger pass
|
||||
|
||||
When this demo was last tested, the official Nuxt Content v3 custom transformers
|
||||
and custom collections examples did not work.
|
||||
|
||||
:::
|
||||
|
||||
[ViteJS modules](/docs/demos/static/vitejs) can be used in Nuxt v3.
|
||||
|
||||
### Installation
|
||||
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
safely imported from `nuxt.config.ts` or transformer or module scripts. As long
|
||||
as the SheetJS modules are not imported in the various `.vue` pages, the library
|
||||
will not be added to the final page bundle!
|
||||
|
||||
### Configuration
|
||||
|
||||
The `vite` property in the NuxtJS config is passed to ViteJS. Plugins and other
|
||||
configuration options can be copied to the object. `vite.config.js` for the
|
||||
[Pure Data Plugin](/docs/demos/static/vitejs#pure-data-plugin) is shown below:
|
||||
|
||||
```js title="vite.config.js (raw ViteJS)"
|
||||
import { readFileSync } from 'fs';
|
||||
import { read, utils } from 'xlsx';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
assetsInclude: ['**/*.xlsx'], // xlsx file should be treated as assets
|
||||
|
||||
plugins: [
|
||||
{ // this plugin handles ?sheetjs tags
|
||||
name: "vite-sheet",
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\?sheetjs$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
return `export default JSON.parse('${JSON.stringify(data).replace(/\\/g, "\\\\")}')`;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
The `assetsInclude` and `plugins` properties should be added within the `vite`
|
||||
property in the object passed to `defineNuxtConfig`.
|
||||
|
||||
:::danger pass
|
||||
|
||||
NuxtJS does not properly honor the `?sheetjs` tag! As a result, the transform
|
||||
explicitly tests for the `.xlsx` extension.
|
||||
|
||||
:::
|
||||
|
||||
```ts title="nuxt.config.ts"
|
||||
import { readFileSync } from 'fs';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
// highlight-next-line
|
||||
vite: { // these options are passed to ViteJS
|
||||
assetsInclude: ['**/*.xlsx'], // xlsx file should be treated as assets
|
||||
|
||||
plugins: [
|
||||
{ // this plugin handles .xlsx
|
||||
name: "vite-sheet",
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\.xlsx$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
return `export default JSON.parse('${JSON.stringify(data).replace(/\\/g, "\\\\")}')`;
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
// ...
|
||||
```
|
||||
|
||||
### Template Use
|
||||
|
||||
Pages can reference spreadsheets using a relative file reference. The ViteJS
|
||||
plugin will transform files with the `.xlsx` extension.
|
||||
|
||||
```js title="Script section of .vue VueJS page"
|
||||
import data from '../../pres.xlsx'; // data is an array of objects
|
||||
```
|
||||
|
||||
In the template, `data` is an array of objects that works with `v-for`[^4]:
|
||||
|
||||
```xml title="Template section of .vue VueJS page"
|
||||
<table>
|
||||
<thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
<!-- loop over the rows of each worksheet -->
|
||||
<tr v-for="row in data" v-bind:key="row.Index">
|
||||
<!-- here `row` is a row object generated from sheet_to_json -->
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
```
|
||||
|
||||
### Nuxt Content 3 Demo
|
||||
|
||||
1) Create a stock app and install dependencies:
|
||||
|
||||
```bash
|
||||
npx -y nuxi init -t content --packageManager pnpm --no-gitInit sheetjs-nc3 -M ,
|
||||
cd sheetjs-nc3
|
||||
npx -y pnpm install
|
||||
```
|
||||
|
||||
2) Install the SheetJS library and start the server:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npx -y pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
npx -y pnpm dev`}
|
||||
</CodeBlock>
|
||||
|
||||
When the build finishes, the terminal will display a URL like:
|
||||
|
||||
```
|
||||
> Local: http://localhost:3000/
|
||||
```
|
||||
|
||||
The server is listening on that URL. Open the link in a web browser.
|
||||
|
||||
3) Download https://docs.sheetjs.com/pres.xlsx and move to the root folder:
|
||||
|
||||
```bash
|
||||
curl -o pres.xlsx https://docs.sheetjs.com/pres.xlsx
|
||||
```
|
||||
|
||||
4) Replace `nuxt.config.ts` with the following codeblock:
|
||||
|
||||
```ts title="nuxt.config.ts"
|
||||
import { readFileSync } from 'fs';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
vite: { // these options are passed to ViteJS
|
||||
assetsInclude: ['**/*.xlsx'], // xlsx file should be treated as assets
|
||||
|
||||
plugins: [
|
||||
{ // this plugin handles .xlsx
|
||||
name: "vite-sheet",
|
||||
transform(_code, id) {
|
||||
if(!id.match(/\.xlsx$/)) return;
|
||||
var wb = read(readFileSync(id.replace(/\?sheetjs$/, "")));
|
||||
var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
return `export default JSON.parse('${JSON.stringify(data).replace(/\\/g, "\\\\")}')`;
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
modules: [
|
||||
'@nuxt/content',
|
||||
],
|
||||
devtools: { enabled: true },
|
||||
});
|
||||
```
|
||||
|
||||
5) Create a new file `app.vue` with the following contents:
|
||||
|
||||
```jsx title="app.vue (create new file)"
|
||||
<script setup>
|
||||
import data from '../../pres.xlsx'
|
||||
</script>
|
||||
<template>
|
||||
<table><thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
<tr v-for="row in data" v-bind:key="row.Index">
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</template>
|
||||
```
|
||||
|
||||
6) Refresh the browser window. This page should now display an HTML table.
|
||||
|
||||
7) Stop the server (press <kbd>CTRL</kbd>+<kbd>C</kbd> in the terminal window).
|
||||
|
||||
8) Build the static site:
|
||||
|
||||
```bash
|
||||
npx -y yarn run generate
|
||||
npx -y pnpm run generate
|
||||
```
|
||||
|
||||
This will create a static site in `.output/public`, which can be served with:
|
||||
|
@ -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` ).
|
||||
|
@ -56,15 +56,15 @@ This demo was tested in the following environments:
|
||||
|
||||
| OS | Device | NS | Date |
|
||||
|:-----------|:--------------------|:---------|:-----------|
|
||||
| Android 30 | NVIDIA Shield | `8.7.2` | 2024-06-09 |
|
||||
| iOS 15.1 | iPad Pro | `8.7.2` | 2024-06-09 |
|
||||
| Android 30 | NVIDIA Shield | `8.9.2` | 2025-05-06 |
|
||||
| iOS 15.1 | iPad Pro | `8.9.2` | 2025-05-06 |
|
||||
|
||||
**Simulators**
|
||||
|
||||
| OS | Device | NS | Dev Platform | Date |
|
||||
|:-----------|:--------------------|:---------|:-------------|:-----------|
|
||||
| Android 34 | Pixel 3a | `8.7.2` | `darwin-arm` | 2024-06-09 |
|
||||
| iOS 17.5 | iPhone SE (3rd gen) | `8.7.2` | `darwin-arm` | 2024-06-09 |
|
||||
| Android 35 | Pixel 9 Pro XL | `8.9.2` | `darwin-x64` | 2025-05-06 |
|
||||
| iOS 18.4 | iPhone 16 Pro Max | `8.9.2` | `darwin-x64` | 2025-05-06 |
|
||||
| Android 35 | Pixel 9 | `8.8.3` | `win11-x64` | 2024-12-21 |
|
||||
| Android 35 | Pixel 9 | `8.8.3` | `linux-x64` | 2025-01-02 |
|
||||
|
||||
@ -78,15 +78,15 @@ NativeScript 8.6.1 split the telemetry into two parts: "usage" and "error". Both
|
||||
must be disabled separately:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns usage-reporting disable
|
||||
npx -p nativescript ns error-reporting disable
|
||||
npx -y -p nativescript ns usage-reporting disable
|
||||
npx -y -p nativescript ns error-reporting disable
|
||||
```
|
||||
|
||||
To verify telemetry was disabled:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns usage-reporting status
|
||||
npx -p nativescript ns error-reporting status
|
||||
npx -y -p nativescript ns usage-reporting status
|
||||
npx -y -p nativescript ns error-reporting status
|
||||
```
|
||||
|
||||
:::
|
||||
@ -120,6 +120,22 @@ for accessing data and are subject to change in future platform versions.
|
||||
<details>
|
||||
<summary><b>Technical Details</b> (click to show)</summary>
|
||||
|
||||
**iOS**
|
||||
|
||||
The following key/value pairs must be added to `Info.plist`:
|
||||
|
||||
```xml title="App_Resources/iOS/Info.plist (add highlighted lines)"
|
||||
<dict>
|
||||
<!-- highlight-start -->
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<!-- highlight-end -->
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Android**
|
||||
|
||||
Android security has evolved over the years. In newer Android versions, the
|
||||
@ -265,8 +281,8 @@ const wb = read(ab);
|
||||
0) Disable telemetry:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns usage-reporting disable
|
||||
npx -p nativescript ns error-reporting disable
|
||||
npx -y -p nativescript ns usage-reporting disable
|
||||
npx -y -p nativescript ns error-reporting disable
|
||||
```
|
||||
|
||||
1) Follow the official Environment Setup instructions[^8].
|
||||
@ -274,14 +290,14 @@ npx -p nativescript ns error-reporting disable
|
||||
:::caution pass
|
||||
|
||||
In previous test runs, NativeScript did not support the latest Android API.
|
||||
The error message from `npx -p nativescript ns doctor android` clearly stated
|
||||
The error message from `npx -y -p nativescript ns doctor android` clearly stated
|
||||
supported versions:
|
||||
|
||||
<pre>
|
||||
<span {...r}>✖</span> No compatible version of the Android SDK Build-tools are installed on your system. You can install any version in the following range: '>=23 <=33'.
|
||||
</pre>
|
||||
|
||||
If NativeScript does not properly supports the latest API level, a previous API
|
||||
If NativeScript does not properly support the latest API level, an older API
|
||||
version should be installed using Android Studio.
|
||||
|
||||
In a previous test run, the following packages were required:
|
||||
@ -290,14 +306,14 @@ In a previous test run, the following packages were required:
|
||||
- `Android SDK Build-Tools` Version `33.0.2`
|
||||
|
||||
It is recommended to install the SDK Platform and corresponding Android SDK
|
||||
Build-Tools for the latest supported API level.ß
|
||||
Build-Tools for the latest supported API level.
|
||||
|
||||
:::
|
||||
|
||||
2) Test the local system configuration for Android development:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns doctor android
|
||||
npx -y -p nativescript ns doctor android
|
||||
```
|
||||
|
||||
In the last macOS test, the following output was displayed:
|
||||
@ -316,7 +332,7 @@ In the last macOS test, the following output was displayed:
|
||||
<span {...g}>✔</span> Javac is installed and is configured properly.
|
||||
<span {...g}>✔</span> The Java Development Kit (JDK) is installed and is configured properly.
|
||||
<span {...g}>✔</span> Getting NativeScript components versions information...
|
||||
<span {...g}>✔</span> Component nativescript has 8.7.2 version and is up to date.
|
||||
<span {...g}>✔</span> Component nativescript has 8.9.2 version and is up to date.
|
||||
</pre>
|
||||
|
||||
</details>
|
||||
@ -324,7 +340,7 @@ In the last macOS test, the following output was displayed:
|
||||
3) Test the local system configuration for iOS development (macOS only):
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns doctor ios
|
||||
npx -y -p nativescript ns doctor ios
|
||||
```
|
||||
|
||||
In the last macOS test, the following output was displayed:
|
||||
@ -343,9 +359,9 @@ In the last macOS test, the following output was displayed:
|
||||
<span {...g}>✔</span> CocoaPods are configured properly.
|
||||
<span {...g}>✔</span> Your current CocoaPods version is newer than 1.0.0.
|
||||
<span {...g}>✔</span> Python installed and configured correctly.
|
||||
<span {...g}>✔</span> Xcode version 15.4.0 satisfies minimum required version 10.
|
||||
<span {...g}>✔</span> Xcode version 16.3.0 satisfies minimum required version 10.
|
||||
<span {...g}>✔</span> Getting NativeScript components versions information...
|
||||
<span {...g}>✔</span> Component nativescript has 8.7.2 version and is up to date.
|
||||
<span {...g}>✔</span> Component nativescript has 8.9.2 version and is up to date.
|
||||
</pre>
|
||||
|
||||
</details>
|
||||
@ -355,21 +371,21 @@ In the last macOS test, the following output was displayed:
|
||||
4) Create a skeleton NativeScript + Angular app:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns create SheetJSNS --ng
|
||||
npx -y -p nativescript ns create SheetJSNS --ng
|
||||
```
|
||||
|
||||
5) Launch the app in the android simulator to verify the app:
|
||||
5) Launch the app in the Android simulator to verify the app:
|
||||
|
||||
```bash
|
||||
cd SheetJSNS
|
||||
npx -p nativescript ns run android
|
||||
npx -y -p nativescript ns run android
|
||||
```
|
||||
|
||||
(this may take a while)
|
||||
|
||||
Once the simulator launches and the test app is displayed, end the script by
|
||||
selecting the terminal and pressing <kbd>CTRL</kbd>+<kbd>C</kbd>. On Windows, if
|
||||
prompted to `Terminate batch job`, type `y` and press Enter.
|
||||
prompted to `Terminate batch job`, type <kbd>Y</kbd> and press Enter.
|
||||
|
||||
:::note pass
|
||||
|
||||
@ -381,6 +397,23 @@ Emulator start failed with: No emulator image available for device identifier 'u
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
In the most recent test, the build failed with an exception:
|
||||
|
||||
```
|
||||
WARNING: A restricted method in java.lang.System has been called
|
||||
WARNING: java.lang.System::load has been called by net.rubygrapefruit.platform.internal.NativeLibraryLoader in an unnamed module (file:/Users/sheetjs/.gradle/wrapper/dists/gradle-8.7-bin/bhs2wmbdwecv87pi65oeuq5iu/gradle-8.7/lib/native-platform-0.22-milestone-25.jar)
|
||||
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
|
||||
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
|
||||
```
|
||||
|
||||
**The NativeScript Gradle version is incompatible with Java 24!**
|
||||
|
||||
It is strongly recommended to roll back to Java 21.
|
||||
|
||||
:::
|
||||
|
||||
### Add SheetJS
|
||||
|
||||
:::note pass
|
||||
@ -406,11 +439,10 @@ import { Component, OnInit } from '@angular/core'
|
||||
// ...
|
||||
|
||||
export class ItemsComponent implements OnInit {
|
||||
items: Array<Item>
|
||||
// highlight-next-line
|
||||
version = `SheetJS - ${version}`;
|
||||
|
||||
constructor(private itemService: ItemService) {}
|
||||
itemService = inject(ItemService)
|
||||
page = inject(Page)
|
||||
// ...
|
||||
```
|
||||
|
||||
@ -428,7 +460,7 @@ in the title of the action bar:
|
||||
9) End the script and relaunch the app in the Android simulator:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run android
|
||||
npx -y -p nativescript ns run android
|
||||
```
|
||||
|
||||
The title bar should show the version.
|
||||
@ -449,7 +481,7 @@ The title bar should show the version.
|
||||
<Button text="Export File" (tap)="export()" style="padding: 10px"></Button>
|
||||
</StackLayout>
|
||||
<!-- highlight-end -->
|
||||
<ListView [items]="items">
|
||||
<ListView [items]="itemService.items()">
|
||||
<!-- ... -->
|
||||
</ListView>
|
||||
<!-- highlight-next-line -->
|
||||
@ -458,15 +490,15 @@ The title bar should show the version.
|
||||
|
||||
11) Add the `import` and `export` methods in the component script:
|
||||
|
||||
```ts title="src/app/item/items.component.ts"
|
||||
```ts title="src/app/item/items.component.ts (add highlighted lines)"
|
||||
// highlight-start
|
||||
import { version, utils, read, write } from 'xlsx';
|
||||
import { Dialogs, getFileAccess } from '@nativescript/core';
|
||||
import { Folder, knownFolders, path } from '@nativescript/core/file-system';
|
||||
// highlight-end
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
|
||||
import { Item } from './item'
|
||||
import { Component, NO_ERRORS_SCHEMA, inject } from '@angular/core'
|
||||
import { NativeScriptCommonModule, NativeScriptRouterModule } from '@nativescript/angular'
|
||||
import { Page } from '@nativescript/core'
|
||||
import { ItemService } from './item.service'
|
||||
|
||||
// highlight-start
|
||||
@ -476,19 +508,12 @@ function get_url_for_filename(filename: string): string {
|
||||
}
|
||||
// highlight-end
|
||||
|
||||
@Component({
|
||||
selector: 'ns-items',
|
||||
templateUrl: './items.component.html',
|
||||
})
|
||||
export class ItemsComponent implements OnInit {
|
||||
items: Array<Item>
|
||||
version: string = `SheetJS - ${version}`;
|
||||
// ...
|
||||
|
||||
constructor(private itemService: ItemService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.items = this.itemService.getItems()
|
||||
}
|
||||
export class ItemsComponent {
|
||||
version = `SheetJS - ${version}`;
|
||||
itemService = inject(ItemService)
|
||||
page = inject(Page)
|
||||
|
||||
// highlight-start
|
||||
/* Import button */
|
||||
@ -499,13 +524,14 @@ export class ItemsComponent implements OnInit {
|
||||
async export() {
|
||||
}
|
||||
// highlight-end
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
12) End the script and relaunch the app in the Android simulator:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run android
|
||||
npx -y -p nativescript ns run android
|
||||
```
|
||||
|
||||
Two buttons should appear just below the header:
|
||||
@ -534,7 +560,7 @@ Two buttons should appear just below the header:
|
||||
const ws = wb.Sheets[wsname];
|
||||
|
||||
/* update table */
|
||||
this.items = utils.sheet_to_json<Item>(ws);
|
||||
this.itemService.items.set(utils.sheet_to_json(ws));
|
||||
} catch(e) { await Dialogs.alert(e.message); }
|
||||
// highlight-end
|
||||
}
|
||||
@ -547,7 +573,7 @@ Two buttons should appear just below the header:
|
||||
|
||||
try {
|
||||
/* create worksheet from data */
|
||||
const ws = utils.json_to_sheet(this.items);
|
||||
const ws = utils.json_to_sheet(this.itemService.items());
|
||||
|
||||
/* create workbook from worksheet */
|
||||
const wb = utils.book_new();
|
||||
@ -569,7 +595,7 @@ Two buttons should appear just below the header:
|
||||
14) Launch the app in the Android Simulator:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run android
|
||||
npx -y -p nativescript ns run android
|
||||
```
|
||||
|
||||
If the app does not automatically launch, manually open the `SheetJSNS` app.
|
||||
@ -611,8 +637,8 @@ $bytes = [Convert]::FromBase64String($b64)
|
||||
After the header row, insert a row and make the following assignments:
|
||||
|
||||
- Set cell `A2` to `0`
|
||||
- Set cell `B2` to `SheetJS` (type `'SheetJS` in the formula bar)
|
||||
- Set cell `C2` to `Library` (type `'Library` in the formula bar)
|
||||
- Set cell `B2` to `SheetJS` (type `'SheetJS` in the formula bar)
|
||||
- Set cell `C2` to `Library` (type `'Library` in the formula bar)
|
||||
|
||||
After making the changes, the worksheet should look like the following:
|
||||
|
||||
@ -620,8 +646,6 @@ After making the changes, the worksheet should look like the following:
|
||||
id | name | role
|
||||
# highlight-next-line
|
||||
0 | SheetJS | Library
|
||||
1 | Ter Stegen | Goalkeeper
|
||||
3 | Piqué | Defender
|
||||
...
|
||||
```
|
||||
|
||||
@ -671,7 +695,7 @@ Scroll down to ["Fetching Files"](#android-device) for Android device testing.
|
||||
20) Launch the app in the iOS Simulator:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run ios
|
||||
npx -y -p nativescript ns run ios
|
||||
```
|
||||
|
||||
21) Tap "Export File". A dialog will print where the file was written.
|
||||
@ -681,8 +705,8 @@ npx -p nativescript ns run ios
|
||||
After the header row, insert a row and make the following assignments:
|
||||
|
||||
- Set cell `A2` to `0`
|
||||
- Set cell `B2` to `SheetJS` (type `'SheetJS` in the formula bar)
|
||||
- Set cell `C2` to `Library` (type `'Library` in the formula bar)
|
||||
- Set cell `B2` to `SheetJS` (type `'SheetJS` in the formula bar)
|
||||
- Set cell `C2` to `Library` (type `'Library` in the formula bar)
|
||||
|
||||
After making the changes, the worksheet should look like the following:
|
||||
|
||||
@ -690,8 +714,6 @@ After making the changes, the worksheet should look like the following:
|
||||
id | name | role
|
||||
# highlight-next-line
|
||||
0 | SheetJS | Library
|
||||
1 | Ter Stegen | Goalkeeper
|
||||
3 | Piqué | Defender
|
||||
...
|
||||
```
|
||||
|
||||
@ -704,31 +726,21 @@ The first item in the list will change:
|
||||
|
||||
### Fetching Files
|
||||
|
||||
25) In `src/app/item/items.component.ts`, make `ngOnInit` asynchronous:
|
||||
|
||||
```ts title="src/app/item/items.component.ts (replace existing function)"
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.items = await this.itemService.getItems()
|
||||
}
|
||||
```
|
||||
|
||||
26) Replace `item.service.ts` with the following:
|
||||
25) Replace `item.service.ts` with the following:
|
||||
|
||||
```ts title="src/app/item/item.service.ts"
|
||||
import { Injectable } from '@angular/core'
|
||||
|
||||
import { knownFolders, path, getFileAccess } from '@nativescript/core'
|
||||
import { getFile } from '@nativescript/core/http';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
import { Injectable, signal, effect } from '@angular/core'
|
||||
import { knownFolders, path, getFileAccess } from '@nativescript/core';
|
||||
import { getFile } from '@nativescript/core/http';
|
||||
import { Item } from './item'
|
||||
|
||||
interface IPresident { Name: string; Index: number };
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ItemService {
|
||||
private items: Array<Item>;
|
||||
|
||||
async getItems(): Promise<Array<Item>> {
|
||||
items = signal<Item[]>([]);
|
||||
constructor() { effect(() => { (async() => {
|
||||
/* fetch https://docs.sheetjs.com/pres.xlsx */
|
||||
const temp: string = path.join(knownFolders.temp().path, "pres.xlsx");
|
||||
const ab = await getFile("https://docs.sheetjs.com/pres.xlsx", temp)
|
||||
@ -736,32 +748,33 @@ export class ItemService {
|
||||
const wb = read(await getFileAccess().readBufferAsync(ab.path));
|
||||
/* translate the first worksheet to the required Item type */
|
||||
const data = utils.sheet_to_json<IPresident>(wb.Sheets[wb.SheetNames[0]]);
|
||||
return this.items = data.map((pres, id) => ({id, name: pres.Name, role: ""+pres.Index} as Item));
|
||||
}
|
||||
/* update state */
|
||||
this.items.set(data.map((pres, id) => ({id, name: pres.Name, role: ""+pres.Index} as Item)));
|
||||
})(); }); }
|
||||
|
||||
getItem(id: number): Item {
|
||||
return this.items.filter((item) => item.id === id)[0]
|
||||
return this.items().find((item) => item.id === id)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
27) End the script and relaunch the app in the Android simulator:
|
||||
26) End the script and relaunch the app in the Android simulator:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run android
|
||||
npx -y -p nativescript ns run android
|
||||
```
|
||||
|
||||
The app should show Presidential data.
|
||||
|
||||
### Android Device
|
||||
|
||||
28) Connect an Android device using a USB cable.
|
||||
27) Connect an Android device using a USB cable.
|
||||
|
||||
If the device asks to allow USB debugging, tap "Allow".
|
||||
|
||||
29) Close any Android / iOS emulators.
|
||||
28) Close any Android / iOS emulators.
|
||||
|
||||
30) Enable "Legacy External Storage" in the Android app. The manifest is stored
|
||||
29) Enable "Legacy External Storage" in the Android app. The manifest is stored
|
||||
at `App_Resources/Android/src/main/AndroidManifest.xml`:
|
||||
|
||||
```xml title="App_Resources/Android/src/main/AndroidManifest.xml (add highlighted line)"
|
||||
@ -776,13 +789,13 @@ at `App_Resources/Android/src/main/AndroidManifest.xml`:
|
||||
android:hardwareAccelerated="true">
|
||||
```
|
||||
|
||||
31) Install the `@nativescript-community/perms` dependency:
|
||||
30) Install the `@nativescript-community/perms` dependency:
|
||||
|
||||
```bash
|
||||
npm i --save @nativescript-community/perms
|
||||
```
|
||||
|
||||
32) Add the highlighted lines to `items.component.ts`:
|
||||
31) Add the highlighted lines to `items.component.ts`:
|
||||
|
||||
- Import `File` from NativeScript core and `request` from the new dependency:
|
||||
|
||||
@ -815,10 +828,10 @@ import { Component, OnInit } from '@angular/core'
|
||||
} catch(e) { await Dialogs.alert(e.message); }
|
||||
```
|
||||
|
||||
33) Build APK and run on device:
|
||||
32) Build APK and run on device:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run android
|
||||
npx -y -p nativescript ns run android
|
||||
```
|
||||
|
||||
If the Android emulators are closed and an Android device is connected, the last
|
||||
@ -839,22 +852,59 @@ file named `SheetJSNS.xls`.
|
||||
|
||||
### iOS Device
|
||||
|
||||
34) Connect an iOS device using a USB cable
|
||||
33) Connect an iOS device using a USB cable
|
||||
|
||||
35) Close any Android / iOS emulators.
|
||||
34) Close any Android / iOS emulators.
|
||||
|
||||
36) Enable developer code signing certificates:
|
||||
35) Enable developer code signing certificates:
|
||||
|
||||
Open `platforms/ios/SheetJSNS.xcodeproj/project.xcworkspace` in Xcode. Select
|
||||
the "Project Navigator" and select the "App" project. In the main view, select
|
||||
"Signing & Capabilities". Under "Signing", select a team in the dropdown menu.
|
||||
the "Project Navigator" and select `SheetJSNS`. In the main view, select the
|
||||
`SheetJSNS` target. Click "Signing & Capabilities". Under "Signing", select a
|
||||
team in the dropdown menu.
|
||||
|
||||
:::caution pass
|
||||
|
||||
When this demo was last tested, Xcode repeatedly crashed.
|
||||
|
||||
The issue was resolved by cleaning the project:
|
||||
|
||||
```bash
|
||||
npx -y -p nativescript ns platform clean ios
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
36) Add the following key/value pairs to `Info.plist`:
|
||||
|
||||
```xml title="App_Resources/iOS/Info.plist (add highlighted lines)"
|
||||
<dict>
|
||||
<!-- highlight-start -->
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<!-- highlight-end -->
|
||||
```
|
||||
|
||||
37) Run on device:
|
||||
|
||||
```bash
|
||||
npx -p nativescript ns run ios
|
||||
npx -y -p nativescript ns run ios
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
If this is the first time testing an app on a device, the certificate must be
|
||||
trusted on the device:
|
||||
|
||||
Under "Settings" > "General" > "VPN & Device Management", there should be a
|
||||
"Apple Development" certificate in the "DEVELOPER APP" section. Select the
|
||||
certificate and confirm that "SheetJSNS" is listed under "APPS". Tap "Trust ..."
|
||||
and tap "Trust" in the popup.
|
||||
|
||||
:::
|
||||
|
||||
<details open>
|
||||
<summary><b>iOS Device Testing</b> (click to hide)</summary>
|
||||
|
||||
@ -863,8 +913,9 @@ connected to the Internet, a list of Presidents should be displayed.
|
||||
|
||||
Tap "Export File". The app will show an alert. Tap "OK".
|
||||
|
||||
Switch to the "Files" app and open the "Downloads" folder. There should be a new
|
||||
file named `SheetJSNS.xls`.
|
||||
Switch to the "Files" app and repeatedly tap "<". In the "Browse" window, tap
|
||||
"On My iPhone". There should be a new folder named "SheetJSNS". Tap the folder
|
||||
and look for the file named `SheetJSNS.xls`.
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -59,7 +59,7 @@ This demo was tested in the following environments:
|
||||
|:-----------|:------------------|:--------|:---------|:-------------|:-----------|
|
||||
| Android 35 | Pixel 9 Pro XL | `3.7.2` | `3.29.2` | `darwin-x64` | 2025-03-31 |
|
||||
| iOS 18.3 | iPhone 16 Pro Max | `3.7.2` | `3.29.2` | `darwin-x64` | 2025-03-31 |
|
||||
| Android 35 | Pixel 3a | `3.5.0` | `3.24.0` | `win11-x64` | 2024-08-10 |
|
||||
| Android 36 | Pixel 9 Pro XL | `3.7.2` | `3.29.3` | `win11-x64` | 2054-04-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -244,7 +244,7 @@ Run `flutter doctor` and confirm the following items are checked:
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
<pre>
|
||||
<span {...g}>[✓]</span> Android toolchain - develop for Android devices (Android SDK version 35.0.0)
|
||||
<span {...g}>[✓]</span> Android toolchain - develop for Android devices (Android SDK version 35.0.1)
|
||||
</pre>
|
||||
|
||||
</TabItem>
|
||||
@ -260,7 +260,7 @@ Run `flutter doctor` and confirm the following items are checked:
|
||||
On first run, there may be a warning with "Android toolchain":
|
||||
|
||||
```
|
||||
[!] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
|
||||
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
|
||||
! Some Android licenses not accepted. To resolve this, run: flutter doctor
|
||||
--android-licenses
|
||||
```
|
||||
@ -386,9 +386,9 @@ Pixel_9_Pro_XL_API_35 • Pixel 9 Pro XL API 35 • Google • android
|
||||
There should be at least one `android` emulator:
|
||||
|
||||
```
|
||||
Id • Name • Manufacturer • Platform
|
||||
Id • Name • Manufacturer • Platform
|
||||
|
||||
Pixel_3a_API_35 • Pixel 3a API 35 • Google • android
|
||||
Pixel_9_Pro_XL • Pixel 9 Pro XL • Google • android
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -445,14 +445,43 @@ emulator -avd Pixel_9_Pro_XL_API_35
|
||||
|
||||
:::note pass
|
||||
|
||||
If `emulator` cannot be found, the folder must be added to the system path.
|
||||
|
||||
<Tabs groupId="os">
|
||||
<TabItem value="macos" label="macOS">
|
||||
|
||||
On macOS, `~/Library/Android/sdk/emulator/` is the typical location for the
|
||||
`emulator` binary. If it cannot be found, add the folder to `PATH`:
|
||||
`emulator` binary:
|
||||
|
||||
```bash
|
||||
export PATH="$PATH":~/Library/Android/sdk/emulator
|
||||
emulator -avd Pixel_9_Pro_XL_API_35
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
The Android SDK folder can be found in the SDK manager in Android Studio. It is
|
||||
typically `%LOCALAPPDATA%\Android\Sdk`.
|
||||
|
||||
If it is not assigned, create a User environment variable named `ANDROID_HOME`
|
||||
with the value set to the Android SDK folder.
|
||||
|
||||
---
|
||||
|
||||
There are three folders within the Android SDK folder that should be added to
|
||||
the User `PATH` environment variable. Each folder holds a different tool:
|
||||
|
||||
| Folder | Command-line Tool |
|
||||
|:------------------------------------------|:------------------|
|
||||
| `%ANDROID_HOME%\emulator` | `emulator` |
|
||||
| `%ANDROID_HOME%\cmdline-tools\latest\bin` | `avdmanager` |
|
||||
| `%ANDROID_HOME%\platform-tools` | `adb` |
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
:::
|
||||
|
||||
</details>
|
||||
@ -645,6 +674,13 @@ flutter -v -d emulator-5554 run
|
||||
|
||||
</details>
|
||||
|
||||
:::caution pass
|
||||
|
||||
In some test runs on low-power devices, it took 20 seconds for the app to fetch
|
||||
and display data!
|
||||
|
||||
:::
|
||||
|
||||
:::info Troubleshooting
|
||||
|
||||
In some demo runs, the build failed with an Android SDK error:
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -111,6 +111,7 @@ const jwt = new google.auth.JWT({
|
||||
key: creds.private_key,
|
||||
scopes: [
|
||||
'https://www.googleapis.com/auth/spreadsheets', // Google Sheets
|
||||
'https://www.googleapis.com/auth/drive', // Google Drive
|
||||
'https://www.googleapis.com/auth/drive.file', // Google Drive
|
||||
]
|
||||
});
|
||||
@ -495,7 +496,7 @@ At this point `wb` is a SheetJS workbook object[^10].
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2024-06-08 using `googleapis` version `140.0.0`.
|
||||
This demo was last tested on 2025-05-14 using `googleapis` version `148.0.0`.
|
||||
The demo uses Sheets v4 and Drive v3 APIs.
|
||||
|
||||
:::
|
||||
@ -551,10 +552,10 @@ be a selection box. Click the `▼` icon to show the modal.
|
||||
|
||||
If the selection box is missing, expand the browser window.
|
||||
|
||||
3) Click "NEW PROJECT" in the top right corner of the modal.
|
||||
3) Click "New project" in the top right corner of the modal.
|
||||
|
||||
4) In the New Project screen, enter "SheetJS Test" in the Project name textbox
|
||||
and select "No organization" in the Location box. Click "CREATE".
|
||||
and select "No organization" in the Location box. Click "Create".
|
||||
|
||||
A notification will confirm that the project was created:
|
||||
|
||||
@ -569,14 +570,13 @@ The goal of this section is to enable Google Sheets API and Google Drive API.
|
||||
|
||||
:::
|
||||
|
||||
5) Open the Project Selector (`▼` icon) and select "SheetJS Test"
|
||||
5) Click "Select a project" and select "SheetJS Test" from the Recent tab.
|
||||
|
||||
6) In the search bar, type "Enabled" and select "Enabled APIs & services". This
|
||||
item will be in the "PRODUCTS & PAGES" part of the search results.
|
||||
6) In the search bar, type "Enabled" and select "Enabled APIs & services".
|
||||
|
||||
#### Enable Google Sheets API
|
||||
|
||||
7) Near the top of the page, click "+ ENABLE APIS AND SERVICES".
|
||||
7) Near the top of the page, click "+ Enable APIs and services".
|
||||
|
||||
8) In the search bar near the middle of the page (not the search bar at the top),
|
||||
type "Sheets" and press <kbd>Enter</kbd>.
|
||||
@ -585,11 +585,11 @@ In the results page, look for "Google Sheets API". Click the card
|
||||
|
||||
9) In the Product Details screen, click the blue "ENABLE" button.
|
||||
|
||||
10) Click the left arrow (`<-`) next to "API/Service details".
|
||||
10) Click the left arrow (`<-`) next to "API/Service Details".
|
||||
|
||||
#### Enable Google Drive API
|
||||
|
||||
11) Near the top of the page, click "+ ENABLE APIS AND SERVICES".
|
||||
11) Near the top of the page, click "+ Enable APIs and services".
|
||||
|
||||
12) In the search bar near the middle of the page (not the search bar at the top),
|
||||
type "Drive" and press <kbd>Enter</kbd>.
|
||||
@ -614,13 +614,13 @@ the top bar.
|
||||
15) Click the Project Selector (`:·` icon) and select "SheetJS Test".
|
||||
|
||||
16) In the search bar, type "Credentials" and select the "Credentials" item with
|
||||
subtitle "APIs & Services". This item will be in the "PRODUCTS & PAGES" group:
|
||||
subtitle "APIs & Services":
|
||||
|
||||

|
||||
|
||||
17) Click "+ CREATE CREDENTIALS". In the dropdown, select "Service Account"
|
||||
17) Click "+ Create credentials". In the dropdown, select "Service account"
|
||||
|
||||
18) Enter "SheetJService" for Service account name. Click "CREATE AND CONTINUE"
|
||||
18) Enter "SheetJService" for Service account name. Click "Create and continue".
|
||||
|
||||
:::note pass
|
||||
|
||||
@ -628,24 +628,24 @@ The Service account ID is generated automatically.
|
||||
|
||||
:::
|
||||
|
||||
19) In Step 2 "Grant this service account access to project", click CONTINUE
|
||||
19) In Step 2 "Grant this service account access to project", click Continue.
|
||||
|
||||
20) In Step 3 click "DONE". You will be taken back to the credentials screen
|
||||
20) In Step 3 click "Done". You will be taken back to the credentials screen
|
||||
|
||||
#### Create JSON Key
|
||||
|
||||
21) Look for "SheetJService" in the "Service Accounts" table and click the email
|
||||
address in the row.
|
||||
|
||||
22) Click "KEYS" in the horizontal bar near the top of the page.
|
||||
22) Click "Keys" in the horizontal bar near the top of the page.
|
||||
|
||||
23) Click "ADD KEY" and select "Create new key" in the dropdown.
|
||||
23) Click "Add key" and select "Create new key" in the dropdown.
|
||||
|
||||
24) In the popup, select the "JSON" radio button and click "CREATE".
|
||||
24) In the popup, select the "JSON" radio button and click "Create".
|
||||
|
||||
The page will download a JSON file. If prompted, allow the download.
|
||||
|
||||
25) Click "CLOSE"
|
||||
25) Click "Close"
|
||||
|
||||
### Create Document
|
||||
|
||||
@ -675,7 +675,7 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz googlea
|
||||
29) Download [`init.mjs`](pathname:///gsheet/init.mjs):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/gsheet/init.mjs
|
||||
curl -o init.mjs https://docs.sheetjs.com/gsheet/init.mjs
|
||||
```
|
||||
|
||||
Edit the marked lines near the top of the file:
|
||||
@ -713,11 +713,12 @@ Shared a-long-string-of-characters with YOUR_ACCOUNT@gmail.com
|
||||
The long string of characters after "Created Google Workbook" is the ID. Take
|
||||
note of this ID.
|
||||
|
||||
31) Sign into Google Sheets. A shared document "SheetJS Test" should be
|
||||
displayed in the table. It will be owned by the service account.
|
||||
31) Sign into Google Drive and select "Shared with me" from the left sidebar. A
|
||||
shared document "SheetJS Test" should be displayed in the table. It will be
|
||||
owned by the service account.
|
||||
|
||||
32) Open the shared document from step 31 and confirm that the document has two
|
||||
worksheets named "SheetJS1" and "SheetJS2".
|
||||
32) Click `⋮` next to "SheetJS Test" and select "Open with" > "Google Sheets".
|
||||
Confirm that the document has two worksheets named "SheetJS1" and "SheetJS2".
|
||||
|
||||
Confirm the worksheet data matches the following screenshots:
|
||||
|
||||
@ -786,13 +787,13 @@ NUMBERS file.
|
||||
34) Download the [test file `pres.numbers`](https://docs.sheetjs.com/pres.numbers):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/pres.numbers
|
||||
curl -o pres.numbers https://docs.sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
35) Download [`load.mjs`](pathname:///gsheet/load.mjs):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/gsheet/load.mjs
|
||||
curl -o load.mjs https://docs.sheetjs.com/gsheet/load.mjs
|
||||
```
|
||||
|
||||
Edit the marked lines near the top of the file:
|
||||
@ -830,7 +831,7 @@ The goal of this section is to export the raw data from Google Sheets to XLSB.
|
||||
38) Download [`dump.mjs`](pathname:///gsheet/dump.mjs):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/gsheet/dump.mjs
|
||||
curl -o dump.mjs https://docs.sheetjs.com/gsheet/dump.mjs
|
||||
```
|
||||
|
||||
Edit the marked lines near the top of the file:
|
||||
@ -876,7 +877,7 @@ assign a grid of values
|
||||
43) Download [`raw.mjs`](pathname:///gsheet/raw.mjs):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/gsheet/raw.mjs
|
||||
curl -o raw.mjs https://docs.sheetjs.com/gsheet/raw.mjs
|
||||
```
|
||||
|
||||
Edit the marked lines near the top of the file:
|
||||
|
@ -266,7 +266,7 @@ function SheetJSEnregistrez() {
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2024-05-27.
|
||||
This demo was last tested on 2025-05-14.
|
||||
|
||||
:::
|
||||
|
||||
|
336
docz/docs/03-demos/32-extensions/05-vscode.md
Normal file
336
docz/docs/03-demos/32-extensions/05-vscode.md
Normal file
@ -0,0 +1,336 @@
|
||||
---
|
||||
title: Visualizing Data in VS Code
|
||||
sidebar_label: Visual Studio Code
|
||||
description: View Excel files directly in VS Code. Seamlessly browse spreadsheet data without leaving your editor using SheetJS. Navigate between worksheets and pages of data with a responsive
|
||||
pagination_prev: demos/cloud/index
|
||||
pagination_next: demos/bigdata/index
|
||||
sidebar_custom_props:
|
||||
summary: View Excel files directly within Visual Studio Code
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
[Visual Studio Code](https://code.visualstudio.com) is a popular code editor
|
||||
that supports JavaScript extensions for customizing and enhancing functionality.
|
||||
|
||||
The ["Complete Example"](#complete-example) uses SheetJS in a VS Code extension
|
||||
to view Excel files directly within the editor. The extension leverages the VS
|
||||
Code "Custom Editor API"[^2] and "WebView API"[^1] to display spreadsheet data
|
||||
as HTML tables.
|
||||
|
||||
:::tip pass
|
||||
|
||||
["SheetJS Spreadsheet Viewer"](https://marketplace.visualstudio.com/items?itemName=asadbek.sheetjs-demo)
|
||||
is a sample extension based on this demo.
|
||||
|
||||
[The source code](https://git.sheetjs.com/asadbek064/sheetjs-vscode-extension)
|
||||
is available on the SheetJS Git server. Feedback and contributions are welcome!
|
||||
|
||||
:::
|
||||
|
||||

|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was verified in the following deployments:
|
||||
|
||||
| Platform | Architecture | Date |
|
||||
|:-----------------|:-------------|:-----------|
|
||||
| VS Code 1.100.0 | `darwin-arm` | 2025-05-15 | TODO
|
||||
| VSCodium 1.100.0 | `darwin-arm` | 2025-05-15 | TODO
|
||||
| Cursor | `win11-arm` | 2025-05-15 | TODO
|
||||
| Windsurf | `win11-arm` | 2025-05-15 | TODO
|
||||
| Void | `win11-arm` | 2025-05-15 | TODO
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
imported from any component or script in the extension.
|
||||
|
||||
:::caution pass
|
||||
|
||||
The module must be installed as a development dependency. If the module is
|
||||
installed as a normal dependency, `vsce`[^5] (Visual Studio Code Extension
|
||||
Manager) will fail to package or publish your extension correctly.
|
||||
|
||||
<Tabs groupId="pm">
|
||||
<TabItem value="npm" label="npm">
|
||||
<CodeBlock language="bash">{`\
|
||||
npm rm --save xlsx
|
||||
npm i --save-dev https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
<CodeBlock language="bash">{`\
|
||||
pnpm rm xlsx
|
||||
pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn" default>
|
||||
<CodeBlock language="bash">{`\
|
||||
yarn remove xlsx
|
||||
yarn add -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::
|
||||
|
||||
## Extension Architecture
|
||||
|
||||
The VS Code Spreadsheet viewer extension has three main components:
|
||||
|
||||
- **Extension Entry Point:** Registers the extension with VS Code
|
||||
- **Custom Editor Provider:** Handles Excel files and converts them to web content
|
||||
- **WebView Content:** Displays Excel data as HTML tables
|
||||
|
||||
The extension uses VS Code's `Custom Editor API`[^2] to register as a handler for Excel files. When a file is opened,
|
||||
SheetJS parses it and displays the data in a WebView component.
|
||||
|
||||
### Extension Entry Point
|
||||
|
||||
The main entry point registers the custom editor provider:
|
||||
|
||||
```ts title="src/extension.ts"
|
||||
import * as vscode from 'vscode';
|
||||
// highlight-start
|
||||
import { ExcelEditorProvider } from './excelEditorProvider';
|
||||
// highlight-end
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// SheetJS Spreadsheet Viewer extension activating...
|
||||
// highlight-start
|
||||
const provider = ExcelEditorProvider.register(context);
|
||||
context.subscriptions.push(provider);
|
||||
// highlight-end
|
||||
}
|
||||
export function deactivate() {}`}
|
||||
```
|
||||
|
||||
The `custom editor`[^3] is configured to support specific file types, giving us complete control over how each file is
|
||||
presented to the user. Additionally, `custom document`[^4] enables us to maintain and persist the state of each individual
|
||||
file that's opened.
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">
|
||||
{`import * as vscode from 'vscode';
|
||||
// highlight-start
|
||||
import * as XLSX from 'xlsx';
|
||||
import { ExcelDocument } from './excelDocument';
|
||||
// highlight-end
|
||||
|
||||
// A simple class to store document state (one per opened file)
|
||||
class ExcelDocument implements vscode.CustomDocument {
|
||||
constructor(public readonly uri: vscode.Uri) {}
|
||||
dispose() {}
|
||||
}
|
||||
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
public static register(context: vscode.ExtensionContext): vscode.Disposable {
|
||||
return vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
}
|
||||
// ...
|
||||
}`}
|
||||
</CodeBlock>
|
||||
|
||||
### Reading Files
|
||||
|
||||
The extension reads Excel files using the VS Code filesystem API and passes
|
||||
the data to SheetJS for parsing:
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">
|
||||
{`export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
// ...
|
||||
private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<XLSX.WorkBook> {
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
const options: XLSX.ParsingOptions = {
|
||||
type: 'array',
|
||||
cellStyles: true,
|
||||
cellDates: true,
|
||||
};
|
||||
|
||||
return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
|
||||
}
|
||||
|
||||
// This is called when the first time an editor for a given resource is opened
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
}
|
||||
|
||||
// This is called whenever the user opens a new editor
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
|
||||
const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
webviewPanel.webview.html = \`<!DOCTYPE html><html><body>\${htmlTable}</body></html>\`;
|
||||
}
|
||||
}`}
|
||||
</CodeBlock>
|
||||
|
||||
### Usage Flow
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant VSCode as VS Code
|
||||
participant Provider as ExcelEditorProvider
|
||||
participant SheetJS
|
||||
participant WebView
|
||||
|
||||
User->>VSCode: Open .xlsx file
|
||||
VSCode->>Provider: openCustomDocument(uri)
|
||||
Provider-->>VSCode: return ExcelDocument
|
||||
VSCode->>Provider: resolveCustomEditor(document, webviewPanel)
|
||||
Provider->>VSCode: workspace.fs.readFile(document.uri)
|
||||
VSCode-->>Provider: return file data
|
||||
Provider->>SheetJS: XLSX.read(data, options)
|
||||
SheetJS-->>Provider: return workbook
|
||||
Provider->>SheetJS: XLSX.utils.sheet_to_html(sheet)
|
||||
SheetJS-->>Provider: return HTML
|
||||
Provider->>WebView: set webview.html
|
||||
WebView-->>User: Display Excel data
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
1) Create a new VS Code extension
|
||||
|
||||
```bash
|
||||
npx --package yo --package generator-code -- yo code
|
||||
```
|
||||
|
||||
When prompted, enter the following options:
|
||||
|
||||
- `What type of extension do you want to create?`: Select `New Extension (TypeScript)` and press <kbd>Enter</kbd>
|
||||
- `What's the name of your extension?`: Type `sheetjs-demo` and press <kbd>Enter</kbd>
|
||||
- `What's the identifier of your extension?`: Press <kbd>Enter</kbd>
|
||||
- `What's the description of your extension?`: Press <kbd>Enter</kbd>
|
||||
- `Initialize a git repository?`: Type `n` and press <kbd>Enter</kbd>
|
||||
- `Which bundler to use?`: Select `webpack` and press <kbd>Enter</kbd>
|
||||
- `Which package manager to use?`: Select `pnpm` and press <kbd>Enter</kbd>
|
||||
|
||||

|
||||
|
||||
- `Do you want to open the new folder with Visual Studio Code?`: Press <kbd>Enter</kbd>
|
||||
|
||||
2) [Install the dependencies](#integration-details) and start the dev server:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
cd sheetjs-demo
|
||||
pnpm install -D https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
pnpm run watch
|
||||
`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Save the following code snippet to `src/excelEditorProvider.ts`:
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/excelEditorProvider.ts">{`\
|
||||
import * as vscode from 'vscode';
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
class ExcelDocument implements vscode.CustomDocument {
|
||||
constructor(public readonly uri: vscode.Uri) { }
|
||||
dispose() { }
|
||||
}
|
||||
|
||||
export class ExcelEditorProvider implements vscode.CustomReadonlyEditorProvider<ExcelDocument> {
|
||||
public static register(context: vscode.ExtensionContext): vscode.Disposable {
|
||||
return vscode.window.registerCustomEditorProvider(
|
||||
'excelViewer.spreadsheet',
|
||||
new ExcelEditorProvider(),
|
||||
{ webviewOptions: { retainContextWhenHidden: true } } // keep webview state when hidden
|
||||
);
|
||||
}
|
||||
|
||||
private async loadWorkbook(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<XLSX.WorkBook> {
|
||||
const data: Uint8Array = await vscode.workspace.fs.readFile(document.uri);
|
||||
|
||||
const options: XLSX.ParsingOptions = {
|
||||
type: 'array',
|
||||
cellStyles: true,
|
||||
cellDates: true,
|
||||
};
|
||||
|
||||
return XLSX.read(new Uint8Array(data), options); // returns a XLSX.WorkBook
|
||||
}
|
||||
|
||||
// This is called when the first time an editor for a given resource is opened
|
||||
async openCustomDocument(uri: vscode.Uri): Promise<ExcelDocument> {
|
||||
return new ExcelDocument(uri);
|
||||
}
|
||||
|
||||
// This is called whenever the user opens a new editor
|
||||
async resolveCustomEditor(document: ExcelDocument, webviewPanel: vscode.WebviewPanel): Promise<void> {
|
||||
const wb: XLSX.WorkBook = await this.loadWorkbook(document, webviewPanel);
|
||||
const htmlTable = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
|
||||
webviewPanel.webview.html = \`<!DOCTYPE html><html><body>\${htmlTable}</body></html>\`;
|
||||
}
|
||||
}`}
|
||||
</CodeBlock>
|
||||
|
||||
4) Register the custom editor provider in `src/extension.ts`:
|
||||
|
||||
<CodeBlock language="typescript" value="typescript" title="src/extension.ts (replace contents)">{`\
|
||||
import * as vscode from 'vscode';
|
||||
import { ExcelEditorProvider } from './excelEditorProvider';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// SheetJS Spreadsheet Viewer extension activating...
|
||||
const provider = ExcelEditorProvider.register(context);
|
||||
context.subscriptions.push(provider);
|
||||
}
|
||||
export function deactivate() {}`}
|
||||
</CodeBlock>
|
||||
|
||||
5) Register the custom editor in the `contributes` section of `package.json`:
|
||||
|
||||
<CodeBlock language="json" value="json" title="package.json (add highlighted lines)">{`\
|
||||
"main": "./dist/extension.js",
|
||||
"contributes": {
|
||||
// highlight-start
|
||||
"customEditors": [
|
||||
{
|
||||
"viewType": "excelViewer.spreadsheet",
|
||||
"displayName": "SheetJS Demo",
|
||||
"selector": [
|
||||
{ "filenamePattern": "*.xlsx" },
|
||||
{ "filenamePattern": "*.xls" }
|
||||
]
|
||||
}
|
||||
],
|
||||
// highlight-end
|
||||
"commands": [
|
||||
{
|
||||
"command": "sheetjs-demo.helloWorld",
|
||||
"title": "Hello World"
|
||||
}
|
||||
]
|
||||
},
|
||||
`}
|
||||
</CodeBlock>
|
||||
|
||||
6. Inside the editor, open `src/extension.ts` and press <kbd>F5</kbd> or run the command **Debug: Start Debugging**
|
||||
from the Command Palette (<kbd>⇧⌘P</kbd>). This will compile and run the extension in a new Extension Development Host window.
|
||||
|
||||
7. Select the new VSCode Window and open a `.xlsx` or `.xls` file.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[^1]: See [`Webview API`](https://code.visualstudio.com/api/extension-guides/webview) for more details.
|
||||
[^2]: See [`Custom Editor API`](https://code.visualstudio.com/api/extension-guides/custom-editors) documentation for more details.
|
||||
[^3]: See [`Custom Editor`](https://code.visualstudio.com/api/extension-guides/custom-editors#custom-editor) for more details.
|
||||
[^4]: See [`CustomDocument`](https://code.visualstudio.com/api/extension-guides/custom-editors#customdocument) for more details.
|
||||
[^5]: See [`Visual Studio Code Extension Manager`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) for more details.
|
@ -55,7 +55,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:------------------|:-----------|
|
||||
| `darwin-x64` | `18.5` (StataNow) | 2025-01-08 |
|
||||
| `darwin-arm` | `18.5` (StataNow) | 2025-04-24 |
|
||||
| `win11-x64` | `18.5` (StataNow) | 2024-12-19 |
|
||||
| `win11-x64` | `18.5` (StataNow) | 2025-04-28 |
|
||||
| `win11-arm` | `18.5` (StataNow) | 2025-02-23 |
|
||||
| `linux-x64` | `18.5` (StataNow) | 2025-01-09 |
|
||||
|
||||
@ -257,6 +257,22 @@ curl -LO https://www.stata.com/plugins/stplugin.c
|
||||
curl -LO https://www.stata.com/plugins/stplugin.h
|
||||
```
|
||||
|
||||
:::danger pass
|
||||
|
||||
**When this demo was last tested, `stplugin.h` was removed from the website!**
|
||||
|
||||
If the official links do not work, the following files should be used:
|
||||
|
||||
- [`stplugin.c`](pathname:///stata/stplugin.c)
|
||||
- [`stplugin.h`](pathname:///stata/stplugin.h)
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/plugins/stplugin.c
|
||||
curl -LO https://docs.sheetjs.com/plugins/stplugin.h
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
4) Download Duktape. In Windows, the following commands should be run in WSL. In
|
||||
macOS, the commands should be run in the same Terminal session.
|
||||
|
||||
@ -463,67 +479,32 @@ The output will show the import result:
|
||||
(2 vars, 5 obs)
|
||||
</pre>
|
||||
|
||||
20) Open the Data Editor (in Browse or Edit mode) and compare to the screenshot:
|
||||
20) List the dataset:
|
||||
|
||||
```stata
|
||||
browse Name Index
|
||||
list Name Index
|
||||
```
|
||||
|
||||
The result should match the following listing:
|
||||
|
||||
```
|
||||
. list Name Index
|
||||
|
||||
+----------------------+
|
||||
| Name Index |
|
||||
|----------------------|
|
||||
1. | Bill Clinton 42 |
|
||||
2. | GeorgeW Bush 43 |
|
||||
3. | Barack Obama 44 |
|
||||
4. | Donald Trump 45 |
|
||||
5. | Joseph Biden 46 |
|
||||
+----------------------+
|
||||
```
|
||||
|
||||
In the Stata GUI, the Data Editor should match the following screenshot:
|
||||
|
||||

|
||||
|
||||
:::info pass
|
||||
|
||||
In the terminal version of Stata, `browse` does not work:
|
||||
|
||||
```
|
||||
. browse Name Index
|
||||
command browse is unrecognized
|
||||
r(199);
|
||||
```
|
||||
|
||||
The `codebook` command will display details.
|
||||
|
||||
<details>
|
||||
<summary><b>Expected Output</b> (click to show)</summary>
|
||||
|
||||
```text title="Expected output for 80-column terminal windows"
|
||||
-------------------------------------------------------------------------------
|
||||
Name Name
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Type: String (str12)
|
||||
|
||||
Unique values: 5 Missing "": 0/5
|
||||
|
||||
Tabulation: Freq. Value
|
||||
1 "Barack Obama"
|
||||
1 "Bill Clinton"
|
||||
1 "Donald Trump"
|
||||
1 "GeorgeW Bush"
|
||||
1 "Joseph Biden"
|
||||
|
||||
Warning: Variable has embedded blanks.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Index Index
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Type: Numeric (byte)
|
||||
|
||||
Range: [42,46] Units: 1
|
||||
Unique values: 5 Missing .: 0/5
|
||||
|
||||
Tabulation: Freq. Value
|
||||
1 42
|
||||
1 43
|
||||
1 44
|
||||
1 45
|
||||
1 46
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
:::
|
||||
|
||||
[^1]: Run `help import excel` in Stata or see ["import excel"](https://www.stata.com/manuals/dimportexcel.pdf) in the Stata documentation.
|
||||
[^2]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||
|
@ -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"))
|
||||
```
|
||||
|
@ -130,7 +130,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.7.0` | 2025-02-13 |
|
||||
| `win11-x64` | `2.7.0` | 2024-12-20 |
|
||||
| `win11-x64` | `2.7.0` | 2025-04-28 |
|
||||
| `win11-arm` | `2.7.0` | 2025-02-23 |
|
||||
| `linux-x64` | `2.7.0` | 2025-04-21 |
|
||||
| `linux-arm` | `2.7.0` | 2025-02-15 |
|
||||
@ -692,7 +692,7 @@ The main Duktape code can be added to the Zig build pipeline.
|
||||
|
||||
:::note pass
|
||||
|
||||
The following explanation was verified against Zig 0.12.0.
|
||||
The following explanation was verified against Zig 0.14.0.
|
||||
|
||||
:::
|
||||
|
||||
@ -710,7 +710,7 @@ folder must be added to the include path list:
|
||||
```
|
||||
|
||||
The `duktape.c` source file must be added to the build sequence. For Zig version
|
||||
0.12.0, Duktape must be compiled with flags `-std=c99 -fno-sanitize=undefined`
|
||||
0.14.0, Duktape must be compiled with flags `-std=c99 -fno-sanitize=undefined`
|
||||
and linked against `libc` and `libm`:
|
||||
|
||||
```zig title="build.zig"
|
||||
@ -786,7 +786,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `0.14.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.7.0` | `0.13.0` | 2025-02-13 |
|
||||
| `win11-x64` | `2.7.0` | `0.13.0` | 2024-12-20 |
|
||||
| `win11-x64` | `2.7.0` | `0.14.0` | 2025-04-28 |
|
||||
| `win11-arm` | `2.7.0` | `0.13.0` | 2025-02-23 |
|
||||
| `linux-x64` | `2.7.0` | `0.14.0` | 2025-04-21 |
|
||||
| `linux-arm` | `2.7.0` | `0.13.0` | 2025-02-15 |
|
||||
@ -855,8 +855,8 @@ The following commands should be run within WSL bash.
|
||||
For X64 Windows:
|
||||
|
||||
```bash
|
||||
curl -LO https://ziglang.org/download/0.13.0/zig-windows-x86_64-0.13.0.zip
|
||||
unzip zig-windows-x86_64-0.13.0.zip
|
||||
curl -LO https://ziglang.org/download/0.14.0/zig-windows-x86_64-0.14.0.zip
|
||||
unzip zig-windows-x86_64-0.14.0.zip
|
||||
```
|
||||
|
||||
For ARM64 Windows:
|
||||
|
@ -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"
|
||||
@ -1484,6 +1639,7 @@ This demo was last tested in the following deployments:
|
||||
|:-------------|:--------------|:---------|:-----------|
|
||||
| `darwin-x64` | `13.1.201.22` | `3.13.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `13.1.201.22` | `3.13.2` | 2025-04-24 |
|
||||
| `win11-x64` | `13.1.201.22` | `3.11.9` | 2025-04-28 |
|
||||
|
||||
:::
|
||||
|
||||
@ -1548,6 +1704,26 @@ python sheetjs-stpyv8.py pres.xlsx
|
||||
The script will display CSV rows from the first worksheet. It will also create
|
||||
`SheetJSSTPyV8.xlsb`, a workbook that can be opened with a spreadsheet editor.
|
||||
|
||||
:::caution pass
|
||||
|
||||
On Windows, this may fail with a `charmap` error:
|
||||
|
||||
```
|
||||
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 380: character maps to <undefined>
|
||||
```
|
||||
|
||||
`sheetjs-stpyv8.py` must be altered to read `xlsx.full.min.js` with mode `rb`:
|
||||
|
||||
```python title="sheetjs-stpyv8.py (edit highlighted line)"
|
||||
# Read xlsx.full.min.js
|
||||
# highlight-next-line
|
||||
with open("xlsx.full.min.js", "rb") as f:
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Snapshots
|
||||
|
||||
At a high level, V8 snapshots are raw dumps of the V8 engine state. It is much
|
||||
@ -1574,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 |
|
||||
|
||||
|
@ -30,22 +30,23 @@ This demo was tested in the following deployments:
|
||||
|
||||
| OpenJDK | Rhino | Date |
|
||||
|:--------|:---------|:-----------|
|
||||
| 23.0.1 | `1.7.15` | 2025-01-10 |
|
||||
| 22.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 21.0.5 | `1.7.15` | 2025-01-10 |
|
||||
| 20.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 19.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 18.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 17.0.13 | `1.7.15` | 2025-01-10 |
|
||||
| 16.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 15.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 14.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 13.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 12.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 11.0.25 | `1.7.15` | 2025-01-10 |
|
||||
| 10.0.2 | `1.7.15` | 2025-01-10 |
|
||||
| 9.0.4 | `1.7.15` | 2025-01-10 |
|
||||
| 1.8.0 | `1.7.15` | 2025-01-10 |
|
||||
| 24.0.1 | `1.7.15` | 2025-05-06 |
|
||||
| 23.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 22.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 21.0.7 | `1.7.15` | 2025-05-06 |
|
||||
| 20.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 19.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 18.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 17.0.15 | `1.7.15` | 2025-05-06 |
|
||||
| 16.0.1 | `1.7.15` | 2025-05-06 |
|
||||
| 15.0.10 | `1.7.15` | 2025-05-06 |
|
||||
| 14.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 13.0.2 | `1.7.15` | 2025-05-06 |
|
||||
| 12.0.1 | `1.7.15` | 2025-05-06 |
|
||||
| 11.0.27 | `1.7.15` | 2025-05-06 |
|
||||
| 10 | `1.7.15` | 2025-05-06 |
|
||||
| 9.0.4 | `1.7.15` | 2025-05-06 |
|
||||
| 1.8.0 | `1.7.15` | 2025-05-06 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -165,7 +165,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `4.2.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `4.2.0` | 2025-02-13 |
|
||||
| `win11-x64` | `4.1.0` | 2024-12-20 |
|
||||
| `win11-x64` | `4.2.2` | 2026-04-28 |
|
||||
| `win11-arm` | `4.2.0` | 2025-02-23 |
|
||||
| `linux-x64` | `4.1.0` | 2025-01-09 |
|
||||
| `linux-arm` | `4.2.0` | 2025-02-15 |
|
||||
@ -248,7 +248,7 @@ dotnet run
|
||||
|
||||
```bash
|
||||
dotnet nuget add source https://www.myget.org/F/jint/api/v3/index.json
|
||||
dotnet add package Jint --version 4.2.1
|
||||
dotnet add package Jint --version 4.2.2
|
||||
```
|
||||
|
||||
To verify Jint is installed, replace `Program.cs` with the following:
|
||||
@ -283,6 +283,25 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://docs.sheetjs.com/pres.xlsx`}
|
||||
</CodeBlock>
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
|
||||
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"
|
||||
@ -499,7 +518,7 @@ cp bin/Release/net*/linux-arm64/publish/SheetJSJint .
|
||||
For Windows 11 x64, the RID is `win-x64` and the command is:
|
||||
|
||||
```powershell
|
||||
copy .\bin\Release\net9.0\win-x64\publish\SheetJSJint.exe .
|
||||
copy .\bin\Release\net*\win-x64\publish\SheetJSJint.exe .
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
@ -513,7 +532,7 @@ The system cannot find the path specified.
|
||||
The correct command was
|
||||
|
||||
```powershell
|
||||
copy .\bin\x64\Release\net9.0\win-x64\publish\SheetJSJint.exe .
|
||||
copy .\bin\x64\Release\net*\win-x64\publish\SheetJSJint.exe .
|
||||
```
|
||||
|
||||
:::
|
||||
|
@ -107,7 +107,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:-----------|:-----------|:-----------|
|
||||
| `darwin-x64` | `bcd7cc6` | `1.24.1` | 2025-03-31 |
|
||||
| `darwin-arm` | `5ef83b8` | `1.24.0` | 2025-02-13 |
|
||||
| `win11-x64` | `79f3a7e` | `1.23.4` | 2024-12-20 |
|
||||
| `win11-x64` | `bcd7cc6` | `1.24.2` | 2025-04-28 |
|
||||
| `win11-arm` | `5ef83b8` | `1.24.0` | 2025-02-23 |
|
||||
| `linux-x64` | `79f3a7e` | `1.22.0` | 2025-01-02 |
|
||||
| `linux-arm` | `5ef83b8` | `1.19.8` | 2025-02-15 |
|
||||
@ -141,12 +141,48 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://docs.sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl.exe -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
|
||||
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>
|
||||
|
||||
:::
|
||||
|
||||
2) Download [`SheetGoja.go`](pathname:///goja/SheetGoja.go):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/goja/SheetGoja.go
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
```bash
|
||||
curl.exe -LO https://docs.sheetjs.com/goja/SheetGoja.go
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
3) Build the standalone `SheetGoja` binary:
|
||||
|
||||
```bash
|
||||
|
@ -105,22 +105,23 @@ This demo was tested in the following deployments:
|
||||
|
||||
| OpenJDK | Nashorn | Date |
|
||||
|:--------|:----------------|:-----------|
|
||||
| 23.0.1 | 15.4 standalone | 2024-12-17 |
|
||||
| 22.0.2 | 15.4 standalone | 2024-12-17 |
|
||||
| 21.0.5 | 15.4 standalone | 2024-12-17 |
|
||||
| 20.0.2 | 15.4 standalone | 2024-12-17 |
|
||||
| 19.0.2 | 15.4 standalone | 2024-12-17 |
|
||||
| 18.0.2 | 15.4 standalone | 2024-12-17 |
|
||||
| 17.0.13 | 15.4 standalone | 2024-12-17 |
|
||||
| 16.0.1 | 15.4 standalone | 2024-12-17 |
|
||||
| 15.0.10 | 15.4 standalone | 2024-12-17 |
|
||||
| 14.0.2 | Built-in | 2024-12-17 |
|
||||
| 13.0.14 | Built-in | 2024-12-17 |
|
||||
| 12.0.2 | Built-in | 2024-12-17 |
|
||||
| 11.0.25 | Built-in | 2024-12-17 |
|
||||
| 10.0.2 | Built-in | 2024-12-17 |
|
||||
| 9 | Built-in | 2024-12-17 |
|
||||
| 1.8.0 | Built-in | 2024-12-17 |
|
||||
| 24.0.1 | 15.4 standalone | 2025-05-06 |
|
||||
| 23.0.2 | 15.4 standalone | 2025-05-06 |
|
||||
| 22.0.2 | 15.4 standalone | 2025-05-06 |
|
||||
| 21.0.7 | 15.4 standalone | 2025-05-06 |
|
||||
| 20.0.2 | 15.4 standalone | 2025-05-06 |
|
||||
| 19.0.2 | 15.4 standalone | 2025-05-06 |
|
||||
| 18.0.2 | 15.4 standalone | 2025-05-06 |
|
||||
| 17.0.15 | 15.4 standalone | 2025-05-06 |
|
||||
| 16.0.1 | 15.4 standalone | 2025-05-06 |
|
||||
| 15.0.10 | 15.4 standalone | 2025-05-06 |
|
||||
| 14.0.2 | Built-in | 2025-05-06 |
|
||||
| 13.0.2 | Built-in | 2025-05-06 |
|
||||
| 12.0.1 | Built-in | 2025-05-06 |
|
||||
| 11.0.27 | Built-in | 2025-05-06 |
|
||||
| 10 | Built-in | 2025-05-06 |
|
||||
| 9.0.4 | Built-in | 2025-05-06 |
|
||||
| 1.8.0 | Built-in | 2025-05-06 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -374,33 +374,33 @@ fork, which powers React Native for Windows, does have built-in support[^5]
|
||||
|
||||
| Architecture | Git Commit | Date |
|
||||
|:-------------|:-----------|:-----------|
|
||||
| `win11-x64` | `4c64b05` | 2024-12-20 |
|
||||
| `win11-x64` | `254fb48` | 2025-04-28 |
|
||||
| `win11-arm` | `4c64b05` | 2025-02-23 |
|
||||
|
||||
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.
|
||||
|
||||
:::
|
||||
|
||||
@ -690,7 +690,7 @@ cd sheetjs-hermes
|
||||
```bash
|
||||
git clone https://github.com/microsoft/hermes-windows
|
||||
cd hermes-windows
|
||||
git checkout 4c64b05
|
||||
git checkout 254fb48
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -849,7 +849,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `0.13.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `0.13.0` | 2025-04-23 |
|
||||
| `win11-x64` | `0.13.0` | 2024-12-20 |
|
||||
| `win11-x64` | `0.13.0` | 2025-04-28 |
|
||||
| `win11-arm` | `0.13.0` | 2025-02-23 |
|
||||
| `linux-x64` | `0.13.0` | 2025-04-21 |
|
||||
|
||||
@ -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.
|
||||
|
@ -89,7 +89,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:---------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.6.10` | `2.10.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `2.6.10` | `2.10.0` | 2025-02-13 |
|
||||
| `win11-x64` | `3.3.6` | `2.10.0` | 2024-12-20 |
|
||||
| `win11-x64` | `3.3.8` | `2.10.0` | 2025-04-28 |
|
||||
| `win11-arm` | `3.2.3` | `2.10.0` | 2025-02-23 |
|
||||
| `linux-x64` | `3.2.3` | `2.10.0` | 2025-04-21 |
|
||||
| `linux-arm` | `3.1.2` | `2.10.0` | 2025-02-15 |
|
||||
@ -157,12 +157,47 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://docs.sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
<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>
|
||||
|
||||
:::
|
||||
|
||||
3) Download [`ExecSheetJS.rb`](pathname:///execjs/ExecSheetJS.rb):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/execjs/ExecSheetJS.rb
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
```bash
|
||||
curl.exe -LO https://docs.sheetjs.com/execjs/ExecSheetJS.rb
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
4) Run the demo:
|
||||
|
||||
```bash
|
||||
|
@ -134,7 +134,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:-----------|:-----------|
|
||||
| `darwin-x64` | `36becec` | 2025-03-31 |
|
||||
| `darwin-arm` | `e26c81f` | 2025-01-13 |
|
||||
| `win11-x64` | `e26c81f` | 2024-12-19 |
|
||||
| `win11-x64` | `36becec` | 2025-04-28 |
|
||||
| `win11-arm` | `e26c81f` | 2025-02-23 |
|
||||
| `linux-x64` | `e26c81f` | 2025-01-09 |
|
||||
|
||||
@ -575,7 +575,7 @@ If successful, the program will print the contents of the first sheet as CSV.
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was last tested on 2025-03-31 against `ch` commit `36becec`.
|
||||
This demo was last tested on 2025-04-28 against `ch` commit `36becec`.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -106,7 +106,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `0.20.0` | 2025-03-31 |
|
||||
| `darwin-arm` | `0.20.0` | 2025-02-13 |
|
||||
| `win11-x64` | `0.20.0` | 2024-12-19 |
|
||||
| `win11-x64` | `0.20.0` | 2025-04-28 |
|
||||
| `win11-arm` | `0.20.0` | 2025-02-23 |
|
||||
| `linux-x64` | `0.20.0` | 2025-04-21 |
|
||||
| `linux-arm` | `0.20.0` | 2025-02-15 |
|
||||
@ -152,12 +152,47 @@ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://docs.sheetjs.com/pres.xlsx`}
|
||||
</CodeBlock>
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
<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 [`main.rs`](pathname:///boa/main.rs) and replace `src/main.rs`:
|
||||
|
||||
```bash
|
||||
curl -L -o src/main.rs https://docs.sheetjs.com/boa/main.rs
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
PowerShell `curl` is incompatible with the official `curl` program. The command
|
||||
may fail with a parameter error:
|
||||
|
||||
```
|
||||
Invoke-WebRequest : A parameter cannot be found that matches parameter name 'LO'.
|
||||
```
|
||||
|
||||
`curl.exe` must be used instead:
|
||||
|
||||
```bash
|
||||
curl.exe -L -o src/main.rs https://docs.sheetjs.com/boa/main.rs
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
5) Build and run the app in release mode:
|
||||
|
||||
```bash
|
||||
|
@ -54,13 +54,14 @@ This demo was tested in the following deployments:
|
||||
|
||||
| OpenJDK | GraalJS | Date |
|
||||
|:--------|:--------|:-----------|
|
||||
| 23.0.1 | 24.1.1 | 2024-12-17 |
|
||||
| 22.0.2 | 24.1.1 | 2024-12-17 |
|
||||
| 21.0.5 | 24.1.1 | 2024-12-17 |
|
||||
| 20.0.2 | 24.1.1 | 2024-12-17 |
|
||||
| 19.0.2 | 24.1.1 | 2024-12-17 |
|
||||
| 18.0.2 | 24.1.1 | 2024-12-17 |
|
||||
| 17.0.13 | 24.1.1 | 2024-12-17 |
|
||||
| 24.0.1 | 24.2.1 | 2025-05-06 |
|
||||
| 23.0.2 | 24.2.1 | 2025-05-06 |
|
||||
| 22.0.2 | 24.2.1 | 2025-05-06 |
|
||||
| 21.0.7 | 24.2.1 | 2025-05-06 |
|
||||
| 20.0.2 | 24.2.1 | 2025-05-06 |
|
||||
| 19.0.2 | 24.2.1 | 2025-05-06 |
|
||||
| 18.0.2 | 24.2.1 | 2025-05-06 |
|
||||
| 17.0.15 | 24.2.1 | 2025-05-06 |
|
||||
|
||||
:::
|
||||
|
||||
@ -69,14 +70,14 @@ This demo was tested in the following deployments:
|
||||
0) Download GraalJS and its dependencies:
|
||||
|
||||
```bash
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-scriptengine/24.1.1/js-scriptengine-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-language/24.1.1/js-language-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/polyglot/polyglot/24.1.1/polyglot-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/collections/24.1.1/collections-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/truffle/truffle-api/24.1.1/truffle-api-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/nativeimage/24.1.1/nativeimage-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/shadowed/icu4j/24.1.1/icu4j-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/regex/regex/24.1.1/regex-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-scriptengine/24.2.1/js-scriptengine-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-language/24.2.1/js-language-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/polyglot/polyglot/24.2.1/polyglot-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/collections/24.2.1/collections-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/truffle/truffle-api/24.2.1/truffle-api-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/nativeimage/24.2.1/nativeimage-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/shadowed/icu4j/24.2.1/icu4j-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/regex/regex/24.2.1/regex-24.2.1.jar"
|
||||
```
|
||||
|
||||
1) Download the SheetJS Standalone script, shim script and test file. Move all
|
||||
@ -117,14 +118,14 @@ CSV rows from the first worksheet.
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```bash
|
||||
java -cp ".:js-scriptengine-24.1.1.jar:js-language-24.1.1.jar:polyglot-24.1.1.jar:collections-24.1.1.jar:truffle-api-24.1.1.jar:nativeimage-24.1.1.jar:icu4j-24.1.1.jar:regex-24.1.1.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
java -cp ".:js-scriptengine-24.2.1.jar:js-language-24.2.1.jar:polyglot-24.2.1.jar:collections-24.2.1.jar:truffle-api-24.2.1.jar:nativeimage-24.2.1.jar:icu4j-24.2.1.jar:regex-24.2.1.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
```bash
|
||||
java -cp ".;js-scriptengine-24.1.1.jar;js-language-24.1.1.jar;polyglot-24.1.1.jar;collections-24.1.1.jar;truffle-api-24.1.1.jar;nativeimage-24.1.1.jar;icu4j-24.1.1.jar;regex-24.1.1.jar" -D"polyglot.js.nashorn-compat=true" SheetJSNashorn pres.xlsx
|
||||
java -cp ".;js-scriptengine-24.2.1.jar;js-language-24.2.1.jar;polyglot-24.2.1.jar;collections-24.2.1.jar;truffle-api-24.2.1.jar;nativeimage-24.2.1.jar;icu4j-24.2.1.jar;regex-24.2.1.jar" -D"polyglot.js.nashorn-compat=true" SheetJSNashorn pres.xlsx
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@ -154,14 +155,14 @@ cd sheethorn
|
||||
<TabItem value="unix" label="Linux/MacOS">
|
||||
|
||||
```bash
|
||||
java -cp ".:js-scriptengine-24.1.1.jar:js-language-24.1.1.jar:polyglot-24.1.1.jar:collections-24.1.1.jar:truffle-api-24.1.1.jar:nativeimage-24.1.1.jar:icu4j-24.1.1.jar:regex-24.1.1.jar:SheetJSNashorn.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
java -cp ".:js-scriptengine-24.2.1.jar:js-language-24.2.1.jar:polyglot-24.2.1.jar:collections-24.2.1.jar:truffle-api-24.2.1.jar:nativeimage-24.2.1.jar:icu4j-24.2.1.jar:regex-24.2.1.jar:SheetJSNashorn.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="win" label="Windows">
|
||||
|
||||
```bash
|
||||
java -cp ".;js-scriptengine-24.1.1.jar;js-language-24.1.1.jar;polyglot-24.1.1.jar;collections-24.1.1.jar;truffle-api-24.1.1.jar;nativeimage-24.1.1.jar;icu4j-24.1.1.jar;regex-24.1.1.jar;SheetJSNashorn.jar" -D"polyglot.js.nashorn-compat=true" SheetJSNashorn pres.xlsx
|
||||
java -cp ".;js-scriptengine-24.2.1.jar;js-language-24.2.1.jar;polyglot-24.2.1.jar;collections-24.2.1.jar;truffle-api-24.2.1.jar;nativeimage-24.2.1.jar;icu4j-24.2.1.jar;regex-24.2.1.jar;SheetJSNashorn.jar" -D"polyglot.js.nashorn-compat=true" SheetJSNashorn pres.xlsx
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -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>
|
||||
|
@ -367,7 +367,7 @@ This,is,a,Test
|
||||
The test suite is regularly run against a number of modern and legacy browsers
|
||||
using [Sauce Labs](https://saucelabs.com/).
|
||||
|
||||
The following chart shows test results on 2024-10-20 for version `0.20.3`:
|
||||
The following chart shows test results on 2025-05-15 for version `0.20.3`:
|
||||
|
||||
[](https://saucelabs.com/u/sheetjs)
|
||||
|
||||
|
@ -15,6 +15,10 @@
|
||||
},
|
||||
"overrides": {
|
||||
"@cmfcmf/docusaurus-search-local": {
|
||||
"@algolia/autocomplete-theme-classic": "1.19.1",
|
||||
"@algolia/autocomplete-js": "1.19.1",
|
||||
"@algolia/client-search": "5.25.0",
|
||||
"algoliasearch": "5.25.0",
|
||||
"@docusaurus/core": "3.7.0"
|
||||
}
|
||||
},
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 12 KiB |
@ -1,4 +1,4 @@
|
||||
import SheetJSModule from './sheetmodule'
|
||||
import SheetJSModule from './sheetmodule';
|
||||
|
||||
export default defineNuxtConfig({
|
||||
// @ts-ignore
|
@ -2,7 +2,7 @@
|
||||
import { defineTransformer } from "@nuxt/content/transformers/utils";
|
||||
import { read, utils } from "xlsx";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from 'node:path';
|
||||
import { resolve } from "node:path";
|
||||
|
||||
export default defineTransformer({
|
||||
name: 'sheetformer',
|
14
docz/static/stata/stplugin.c
Normal file
14
docz/static/stata/stplugin.c
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
stplugin.c, version 3.0
|
||||
copyright (c) 2003, 2006, 2015 StataCorp LP
|
||||
*/
|
||||
|
||||
#include "stplugin.h"
|
||||
|
||||
ST_plugin *_stata_ ;
|
||||
|
||||
STDLL pginit(ST_plugin *p)
|
||||
{
|
||||
_stata_ = p ;
|
||||
return(SD_PLUGINVER) ;
|
||||
}
|
246
docz/static/stata/stplugin.h
Normal file
246
docz/static/stata/stplugin.h
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
stplugin.h, version 3.0.0
|
||||
copyright (c) 2003, 2004, 2006, 2015 StataCorp LP
|
||||
*/
|
||||
#if !defined(STPLUGIN_H)
|
||||
#define STPLUGIN_H
|
||||
|
||||
#if !defined(SD_FASTMODE)
|
||||
#define SD_SAFEMODE
|
||||
#endif
|
||||
|
||||
#define HP9000 1
|
||||
#define OPUNIX 2
|
||||
#define APPLEMAC 3
|
||||
#define STWIN32 4
|
||||
|
||||
#ifndef SYSTEM
|
||||
#define SYSTEM STWIN32
|
||||
#endif
|
||||
|
||||
typedef signed char ST_sbyte ;
|
||||
typedef unsigned char ST_ubyte ;
|
||||
typedef int ST_int ;
|
||||
typedef unsigned ST_unsigned ;
|
||||
typedef short int ST_int2 ;
|
||||
typedef int ST_int4 ;
|
||||
typedef long ST_long ;
|
||||
typedef unsigned int ST_uint4 ;
|
||||
typedef float ST_float ;
|
||||
typedef double ST_double ;
|
||||
typedef unsigned char ST_boolean ;
|
||||
typedef int ST_retcode ;
|
||||
typedef double * ST_dmkey ;
|
||||
|
||||
#if !defined(bTrue)
|
||||
#define bTrue 1
|
||||
#define bFalse 0
|
||||
#endif
|
||||
|
||||
#define SF_HIWORD(x) ((ST_int2)((ST_int4)(x)>>16))
|
||||
#define SF_LOWORD(x) ((ST_int2)(x))
|
||||
#define SF_MAKELONG(x,y) ((ST_int4)(((ST_int2)(x))|((ST_int4)((ST_int2)(y)))<<16))
|
||||
|
||||
#if SYSTEM==STWIN32
|
||||
#if __cplusplus
|
||||
#define STDLL extern "C" __declspec(dllexport) ST_retcode
|
||||
#else
|
||||
#define STDLL extern __declspec(dllexport) ST_retcode
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SYSTEM!=STWIN32
|
||||
#if SYSTEM==HP9000
|
||||
#include <dl.h>
|
||||
#endif
|
||||
|
||||
#if SYSTEM==OPUNIX
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#if __cplusplus
|
||||
#define STDLL extern "C" ST_retcode
|
||||
#else
|
||||
#define STDLL ST_retcode
|
||||
#endif
|
||||
#define LPSTR char *
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
ST_int type ;
|
||||
ST_int nel ;
|
||||
ST_int m ;
|
||||
ST_int n ;
|
||||
} ST_matinfo ;
|
||||
|
||||
#define SD_PLUGINMAJ 3
|
||||
#define SD_PLUGINMIN 0
|
||||
#define SD_PLUGINVER SF_MAKELONG(SD_PLUGINMAJ,SD_PLUGINMIN)
|
||||
|
||||
typedef void (* ST_VV) (void) ;
|
||||
typedef ST_int (* ST_IV) (void) ;
|
||||
typedef ST_int (* ST_IS) (char *) ;
|
||||
typedef void (* ST_VU) (ST_ubyte) ;
|
||||
typedef ST_boolean (* ST_BI) (ST_int) ;
|
||||
typedef ST_boolean (* ST_BII) (ST_int,ST_int) ;
|
||||
typedef ST_boolean (* ST_BD) (ST_double) ;
|
||||
typedef ST_int (* ST_III) (ST_int,ST_int) ;
|
||||
typedef ST_double (* ST_DII) (ST_int,ST_int) ;
|
||||
typedef ST_double (* ST_DV) (void) ;
|
||||
typedef ST_double (* ST_DD) (ST_double) ;
|
||||
typedef ST_double (* ST_DDD) (ST_double,ST_double) ;
|
||||
typedef ST_int (* ST_ISS) (char *,char *) ;
|
||||
typedef ST_int (* ST_ISI) (char *,ST_int) ;
|
||||
typedef ST_int (* ST_ISSI) (char *,char *,ST_int) ;
|
||||
typedef void (* ST_VSD) (char *,ST_double) ;
|
||||
typedef ST_int (* ST_ISD) (char *, ST_double) ;
|
||||
typedef ST_int (* ST_ISDp) (char *,ST_double *) ;
|
||||
typedef ST_int (* ST_ISDpIIIII) (char *,ST_int,ST_double *,ST_int,ST_int,ST_int,ST_int,ST_int) ;
|
||||
typedef ST_int (* ST_ISIID) (char *, ST_int, ST_int, ST_double) ;
|
||||
typedef ST_int (* ST_ISIIDp) (char *,ST_int,ST_int,ST_double *) ;
|
||||
typedef ST_int (* ST_ISDpI) (char *,ST_double *,ST_int) ;
|
||||
typedef void (* ST_VSMip) (char *,ST_matinfo *) ;
|
||||
typedef ST_int (* ST_IIIDp) (ST_int, ST_int, ST_double *) ;
|
||||
typedef ST_int (* ST_IIID) (ST_int, ST_int, ST_double) ;
|
||||
typedef char * (* ST_SSI) (char *,ST_int) ;
|
||||
typedef char * (* ST_SSSD) (char *,char *,ST_double) ;
|
||||
typedef char * (* ST_SSSDM) (char *,char *,ST_double, ST_dmkey) ;
|
||||
typedef ST_int (* ST_IIIS) (ST_int, ST_int, char *) ;
|
||||
typedef ST_int (* ST_IIISI) (ST_int, ST_int, char *, ST_int) ;
|
||||
|
||||
typedef struct {
|
||||
ST_IS spoutsml ;
|
||||
ST_IS spoutnosml ;
|
||||
ST_VV spoutflush ;
|
||||
ST_VU set_outputlevel ;
|
||||
ST_ISI get_input ;
|
||||
|
||||
ST_IV pollstd ;
|
||||
ST_IV pollnow ;
|
||||
|
||||
ST_SSSD safereforms ;
|
||||
ST_SSSDM safereforml ;
|
||||
|
||||
ST_SSI gettok ;
|
||||
|
||||
ST_ISS macresave ;
|
||||
ST_ISSI macuse ;
|
||||
|
||||
ST_ISDp scalaruse ;
|
||||
ST_ISDp scalarsave ;
|
||||
|
||||
ST_ISDpIIIII matrixstore ;
|
||||
ST_ISDpI matrixload ;
|
||||
ST_VSMip matrixinfo ;
|
||||
ST_ISIIDp matrixel ;
|
||||
ST_int matsize ;
|
||||
|
||||
ST_DII data, safedata ;
|
||||
|
||||
ST_IV nobs ;
|
||||
ST_IV nvar ;
|
||||
|
||||
ST_double missval ;
|
||||
ST_BD ismissing ;
|
||||
|
||||
ST_ISI stfindvar ;
|
||||
ST_BI isstr ;
|
||||
ST_VSD abvarfcn ;
|
||||
|
||||
ST_int *stopflag ;
|
||||
|
||||
ST_DDD stround ;
|
||||
ST_DD stsqrt ;
|
||||
ST_DDD stpow ;
|
||||
ST_DD stlog ;
|
||||
ST_DD stexp ;
|
||||
ST_DV strandom ;
|
||||
|
||||
ST_IIID store ;
|
||||
ST_IIID safestore ;
|
||||
ST_IIIS sstore ;
|
||||
ST_BI selobs ;
|
||||
ST_IV nobs1 ;
|
||||
ST_IV nobs2 ;
|
||||
ST_IV nvars ;
|
||||
ST_IS spouterr ;
|
||||
ST_ISIIDp safematel ;
|
||||
ST_ISIID safematstore ;
|
||||
ST_ISIIDp matel ;
|
||||
ST_ISIID matstore ;
|
||||
ST_IIIDp safevdata ;
|
||||
ST_IIIDp vdata ;
|
||||
ST_IS colsof ;
|
||||
ST_IS rowsof ;
|
||||
ST_ISD scalsave ;
|
||||
|
||||
ST_IIIS sdata ;
|
||||
|
||||
ST_int2 major ;
|
||||
ST_int2 minor ;
|
||||
ST_BI isstrl ;
|
||||
ST_BII isbinary ;
|
||||
ST_III sdatalen ;
|
||||
ST_IIISI strldata ;
|
||||
} ST_plugin ;
|
||||
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" ST_plugin *_stata_ ;
|
||||
#else
|
||||
extern ST_plugin *_stata_ ;
|
||||
#endif
|
||||
STDLL pginit(ST_plugin *p) ;
|
||||
|
||||
#define SF_display(a) ((_stata_)->spoutsml((a)))
|
||||
#define SF_error(a) ((_stata_)->spouterr((a)))
|
||||
|
||||
#define SF_poll ((_stata_)->pollstd)
|
||||
#define SW_stopflag (*((_stata_)->stopflag))
|
||||
|
||||
#define SF_macro_save(m,t) ((_stata_)->macresave((m),(t)))
|
||||
#define SF_macro_use(m,d,l) ((_stata_)->macuse((m),(d),(l)))
|
||||
|
||||
#define SF_scal_use(s,d) ((_stata_)->scalaruse((s),(d)))
|
||||
#define SF_scal_save(s,d) ((_stata_)->scalsave((s),(d)))
|
||||
|
||||
#if defined(SD_SAFEMODE)
|
||||
#define SF_mat_el(s,r,c,d) ((_stata_)->safematel((s),(r),(c),(d)))
|
||||
#define SF_mat_store(s,r,c,d) ((_stata_)->safematstore((s),(r),(c),(d)))
|
||||
#else
|
||||
#define SF_mat_el(s,r,c,d) ((_stata_)->matel((s),(r),(c),(d)))
|
||||
#define SF_mat_store(s,r,c,d) ((_stata_)->matstore((s),(r),(c),(d)))
|
||||
#endif
|
||||
#define SV_matsize ((_stata_)->matsize)
|
||||
#define SF_col(s) ((_stata_)->colsof((s)))
|
||||
#define SF_row(s) ((_stata_)->rowsof((s)))
|
||||
|
||||
#if defined(SD_SAFEMODE)
|
||||
#define SF_vdata(i,j,d) ((_stata_)->safevdata((i),(j),(d)))
|
||||
#define SF_vstore(i,j,v) ((_stata_)->safestore((i),(j),(v)))
|
||||
#else
|
||||
#define SF_vdata(i,j,d) ((_stata_)->vdata((i),(j),(d)))
|
||||
#define SF_vstore(i,j,v) ((_stata_)->store((i),(j),(v)))
|
||||
#endif
|
||||
|
||||
#define SF_nobs ((_stata_)->nobs)
|
||||
#define SF_in1 ((_stata_)->nobs1)
|
||||
#define SF_in2 ((_stata_)->nobs2)
|
||||
#define SF_nvar ((_stata_)->nvar)
|
||||
#define SF_nvars ((_stata_)->nvars)
|
||||
|
||||
#define SF_sstore(i,j,s) ((_stata_)->sstore((i),(j),(s)))
|
||||
#define SF_sdata(i,j,s) ((_stata_)->sdata((i),(j),(s)))
|
||||
#define SF_strldata(i,j,s,l) ((_stata_)->strldata((i),(j),(s),(l)))
|
||||
|
||||
#define SF_sdatalen(i,j) ((_stata_)->sdatalen((i),(j)))
|
||||
#define SF_var_is_string(a) ((_stata_)->isstr(a))
|
||||
#define SF_var_is_strl(a) ((_stata_)->isstrl(a))
|
||||
#define SF_var_is_binary(i,j) ((_stata_)->isbinary((i),(j)))
|
||||
|
||||
#define SV_missval ((_stata_)->missval)
|
||||
|
||||
#define SF_is_missing(z) ((_stata_)->ismissing(z))
|
||||
#define SF_ifobs(z) ((_stata_)->selobs(z))
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="890" height="480" data-created="2024-10-20T20:28:10.455635">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="890" height="480" data-created="2025-05-16T06:48:51.357946">
|
||||
<defs>
|
||||
<style>
|
||||
@font-face {
|
||||
@ -114,7 +114,7 @@
|
||||
|
||||
<svg x="5" y="68" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">131</text>
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">138</text>
|
||||
<use xlink:href="#windows" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
@ -123,7 +123,7 @@
|
||||
|
||||
</svg>
|
||||
|
||||
<svg x="220" y="0" width="119" height="280">
|
||||
<svg x="220" y="0" width="119" height="315">
|
||||
<use x="12" y="7" width="20" height="20" xlink:href="#chrome" fill="#333f4b"></use>
|
||||
<text x="42" y="24" text-anchor="left" class="head">Chrome</text>
|
||||
|
||||
@ -197,6 +197,16 @@
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="272" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">136</text>
|
||||
<use xlink:href="#windows" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
</svg>
|
||||
|
||||
<svg x="330" y="0" width="119" height="105">
|
||||
@ -225,33 +235,13 @@
|
||||
|
||||
</svg>
|
||||
|
||||
<svg x="440" y="0" width="119" height="140">
|
||||
<svg x="440" y="0" width="119" height="70">
|
||||
<use x="12" y="7" width="20" height="20" xlink:href="#ios" fill="#333f4b"></use>
|
||||
<text x="42" y="24" text-anchor="left" class="head">iPad</text>
|
||||
|
||||
|
||||
<svg x="5" y="34" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">11</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.13</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="68" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">13</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.15</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="102" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">15</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">12</text>
|
||||
@ -261,36 +251,16 @@
|
||||
|
||||
</svg>
|
||||
|
||||
<svg x="550" y="0" width="119" height="140">
|
||||
<svg x="550" y="0" width="119" height="70">
|
||||
<use x="12" y="7" width="20" height="20" xlink:href="#ios" fill="#333f4b"></use>
|
||||
<text x="42" y="24" text-anchor="left" class="head">iPhone</text>
|
||||
|
||||
|
||||
<svg x="5" y="34" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">10</text>
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">15</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.12</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="68" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">12</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.15</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="102" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">14</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">11</text>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">12</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
@ -414,7 +384,7 @@
|
||||
|
||||
<svg x="5" y="408" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">130</text>
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">135</text>
|
||||
<use xlink:href="#windows" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
@ -423,83 +393,13 @@
|
||||
|
||||
</svg>
|
||||
|
||||
<svg x="770" y="0" width="119" height="350">
|
||||
<svg x="770" y="0" width="119" height="105">
|
||||
<use x="12" y="7" width="20" height="20" xlink:href="#safari" fill="#333f4b"></use>
|
||||
<text x="42" y="24" text-anchor="left" class="head">Safari</text>
|
||||
|
||||
|
||||
<svg x="5" y="34" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">8</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.10</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="68" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">9</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.11</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="102" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">10</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.12</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="136" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">11</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.13</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="170" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">12</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.13</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="204" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">13</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">10.15</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="238" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">14</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">11</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
</svg>
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="272" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">15</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">12</text>
|
||||
@ -508,9 +408,9 @@
|
||||
|
||||
|
||||
|
||||
<svg x="5" y="306" width="109" height="33" viewBox="0 0 109 33">
|
||||
<svg x="5" y="68" width="109" height="33" viewBox="0 0 109 33">
|
||||
<rect x="0" y="0" fill="#69cc01" width="109" height="33" />
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">16</text>
|
||||
<text x="7" y="22" text-anchor="left" class="browser_version">17</text>
|
||||
<use xlink:href="#mac" x="34" width="15" fill="#000"></use>
|
||||
<text x="53" y="22" text-anchor="left" class="platform_version">13</text>
|
||||
<use xlink:href="#passing" x="90" width="10"></use>
|
||||
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 105 KiB |
BIN
docz/static/vscode/extension-viewing-xls-file.png
Normal file
BIN
docz/static/vscode/extension-viewing-xls-file.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
BIN
docz/static/vscode/yeo-code.png
Normal file
BIN
docz/static/vscode/yeo-code.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 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
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
|
@ -5,14 +5,14 @@ rm -rf sheetjs-graaljs
|
||||
mkdir -p sheetjs-graaljs
|
||||
cd sheetjs-graaljs
|
||||
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-scriptengine/24.1.1/js-scriptengine-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-language/24.1.1/js-language-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/polyglot/polyglot/24.1.1/polyglot-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/collections/24.1.1/collections-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/truffle/truffle-api/24.1.1/truffle-api-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/nativeimage/24.1.1/nativeimage-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/shadowed/icu4j/24.1.1/icu4j-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/regex/regex/24.1.1/regex-24.1.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-scriptengine/24.2.1/js-scriptengine-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/js/js-language/24.2.1/js-language-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/polyglot/polyglot/24.2.1/polyglot-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/collections/24.2.1/collections-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/truffle/truffle-api/24.2.1/truffle-api-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/sdk/nativeimage/24.2.1/nativeimage-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/shadowed/icu4j/24.2.1/icu4j-24.2.1.jar"
|
||||
curl -LO "https://repo1.maven.org/maven2/org/graalvm/regex/regex/24.2.1/regex-24.2.1.jar"
|
||||
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
|
||||
@ -20,19 +20,19 @@ curl -LO https://sheetjs.com/pres.xlsx
|
||||
|
||||
curl -LO https://docs.sheetjs.com/nashorn/SheetJSNashorn.java
|
||||
|
||||
for n in {17..23}; do
|
||||
for n in {17..24}; do
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
rm -fr SheetJSNashorn.class SheetJSNashorn.jar sheethorn
|
||||
javac SheetJSNashorn.java
|
||||
|
||||
java -cp ".:js-scriptengine-24.1.1.jar:js-language-24.1.1.jar:polyglot-24.1.1.jar:collections-24.1.1.jar:truffle-api-24.1.1.jar:nativeimage-24.1.1.jar:icu4j-24.1.1.jar:regex-24.1.1.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
java -cp ".:js-scriptengine-24.2.1.jar:js-language-24.2.1.jar:polyglot-24.2.1.jar:collections-24.2.1.jar:truffle-api-24.2.1.jar:nativeimage-24.2.1.jar:icu4j-24.2.1.jar:regex-24.2.1.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
|
||||
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
|
||||
|
||||
mkdir -p sheethorn
|
||||
cp *.jar pres.xlsx sheethorn
|
||||
cd sheethorn
|
||||
java -cp ".:js-scriptengine-24.1.1.jar:js-language-24.1.1.jar:polyglot-24.1.1.jar:collections-24.1.1.jar:truffle-api-24.1.1.jar:nativeimage-24.1.1.jar:icu4j-24.1.1.jar:regex-24.1.1.jar:SheetJSNashorn.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
java -cp ".:js-scriptengine-24.2.1.jar:js-language-24.2.1.jar:polyglot-24.2.1.jar:collections-24.2.1.jar:truffle-api-24.2.1.jar:nativeimage-24.2.1.jar:icu4j-24.2.1.jar:regex-24.2.1.jar:SheetJSNashorn.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx
|
||||
cd -
|
||||
done
|
@ -18,7 +18,7 @@ curl -L -o asm-analysis-9.5.jar "https://search.maven.org/remotecontent?filepath
|
||||
curl -L -o asm-util-9.5.jar "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-util/9.5/asm-util-9.5.jar"
|
||||
|
||||
# Standalone Nashorn
|
||||
for n in {15..23}; do
|
||||
for n in {15..24}; do
|
||||
echo $n
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
echo $JAVA_HOME
|
@ -42,7 +42,7 @@ public class SheetJSRhino {
|
||||
}
|
||||
EOF
|
||||
|
||||
for n in 1.8 {9..23}; do
|
||||
for n in 1.8 {9..24}; do
|
||||
export JAVA_HOME=`/usr/libexec/java_home -v $n`
|
||||
java -version
|
||||
find . -name \*.class | while read x; do rm $x; done
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user