diff --git a/docz/docs/02-getting-started/02-examples/02-export.md b/docz/docs/02-getting-started/02-examples/02-export.md index 93b5215..46a16cd 100644 --- a/docz/docs/02-getting-started/02-examples/02-export.md +++ b/docz/docs/02-getting-started/02-examples/02-export.md @@ -1165,9 +1165,9 @@ see a preview of the data. The Numbers app can open the file. -[^1]: https://theunitedstates.io/congress-legislators/executive.json is the +[^1]: `https://theunitedstates.io/congress-legislators/executive.json` is the original location of the example dataset. The contributors to the dataset - dedicated the content to the public domain. + dedicated the content to the public domain. When this demo was last tested, [^2]: See ["The Executive Branch"](https://github.com/unitedstates/congress-legislators#the-executive-branch) in the dataset documentation. [^3]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input) diff --git a/docz/docs/02-getting-started/02-examples/06-loader.md b/docz/docs/02-getting-started/02-examples/06-loader.md index 8134b6c..79861b6 100644 --- a/docz/docs/02-getting-started/02-examples/06-loader.md +++ b/docz/docs/02-getting-started/02-examples/06-loader.md @@ -35,17 +35,19 @@ This demo was tested in the following configurations: | Platform | Architecture | Date | |:------------------------------------------------------------------|:-------------|:-----------| -| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-06-17 | -| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-20 | -| 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-06-20 | -| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-06-20 | -| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-21 | -| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-06-20 | -| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-06-21 | -| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-03-06 | -| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | 2025-06-24 | -| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2025-03-25 | +| NVIDIA RTX PRO 6000 (96 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2025-11-15 | +| NVIDIA RTX PRO 6000 (96 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 | +| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2025-11-15 | +| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 | +| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-11-15 | +| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 | +| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `linux-x64` | 2025-11-15 | +| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `win11-x64` | 2025-11-15 | +| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-11-15 | +| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 | +| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-11-15 | +| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | 2025-11-15 | +| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2025-11-15 | SheetJS users have verified this demo in other configurations: @@ -55,6 +57,8 @@ SheetJS users have verified this demo in other configurations: | Platform | Architecture | Demo | |:---------------------------------------------------------------------|:-------------|:------------| | NVIDIA L40 (48 GB VRAM) + i9-13900K (32 GB RAM) | `linux-x64` | LangChainJS | +| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | LangChainJS | +| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | LangChainJS | | NVIDIA RTX 4080 SUPER (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS | | NVIDIA RTX 4080 SUPER (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | LangChainJS | | NVIDIA RTX 4070 Ti SUPER (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS | @@ -878,7 +882,7 @@ npm i --save https://sheet.lol/balls/xlsx-${current}.tgz`} 4) Install dependencies: ```bash -npm i --save @langchain/core@0.3.59 langchain@0.3.28 @langchain/ollama@0.2.2 peggy@3.0.2 +npm i --save @langchain/core@0.3.78 langchain@0.3.36 @langchain/ollama@0.2.4 peggy@3.0.2 ``` :::note pass @@ -887,7 +891,7 @@ In some test runs, there were error messages relating to dependency and peer dependency versions. The `--force` flag will suppress version mismatch errors: ```bash -npm i --save @langchain/core@0.3.59 langchain@0.3.28 @langchain/ollama@0.2.2 peggy@3.0.2 --force +npm i --save @langchain/core@0.3.78 langchain@0.3.36 @langchain/ollama@0.2.4 peggy@3.0.2 --force ``` ::: @@ -921,7 +925,7 @@ ollama pull phi4:14b ```
- Additional steps for Intel GPUs (click to show) + Additional steps for Intel GPUs and AMD Strix Halo (click to show) A different embedding model must be used on Intel GPUs: diff --git a/docz/docs/03-demos/01-math/11-tensorflow.md b/docz/docs/03-demos/01-math/11-tensorflow.md index 0aa15aa..2951eb2 100644 --- a/docz/docs/03-demos/01-math/11-tensorflow.md +++ b/docz/docs/03-demos/01-math/11-tensorflow.md @@ -44,14 +44,15 @@ The NodeJS demo was tested in the following environments: | NodeJS | TF.js | Date | |:------------|:----------|:-----------| -| `22.14.0` | `4.22.0` | 2025-04-21 | -| `20.18.0` | `4.22.0` | 2025-04-21 | +| `24.11.1` | `4.22.0` | 2025-11-15 | +| `22.21.1` | `4.22.0` | 2025-11-15 | +| `20.18.0` | `4.22.0` | 2025-11-15 | The Kaioken demo was tested in the following environments: | Kaioken | TF.js | Date | |:------------|:----------|:-----------| -| `0.37.0` | `4.22.0` | 2025-04-21 | +| `0.44.3` | `4.22.0` | 2025-11-15 | ::: @@ -417,7 +418,7 @@ The SheetJS team strongly recommends using Kaioken in projects using TF.js. 1) Create a new site. ```bash -npm create vite sheetjs-tfjs-kaioken -- --template vanilla-ts +npm create vite sheetjs-tfjs-kaioken -- --template vanilla-ts --no-rolldown --no-interactive cd sheetjs-tfjs-kaioken npm add --save kaioken npm add --save vite-plugin-kaioken -D @@ -443,7 +444,14 @@ export default defineConfig({ "jsx": "preserve", ``` -4) Replace `src/main.ts` with the following codeblock: +4) Edit `tsconfig.json` and remove any lines referencing `verbatimModuleSyntax`. +When the demo was last tested, the file had the following line: + +```js title="tsconfig.json (remove this line if present)" + "verbatimModuleSyntax": true, +``` + +5) Replace `src/main.ts` with the following codeblock: ```js title="src/main.ts" import { mount } from "kaioken"; @@ -453,19 +461,19 @@ const root = document.getElementById("app"); mount(App, root!); ``` -5) Download [`SheetJSTF.tsx`](pathname:///tfjs/SheetJSTF.tsx) to the `src` directory: +6) Download [`SheetJSTF.tsx`](pathname:///tfjs/SheetJSTF.tsx) to the `src` directory: ```bash curl -L -o src/SheetJSTF.tsx https://docs.sheetjs.com/tfjs/SheetJSTF.tsx ``` -6) Install SheetJS and TF.js dependencies: +7) Install SheetJS and TF.js dependencies: {`\ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @tensorflow/tfjs`} -7) Start the development server: +8) Start the development server: ```bash npm run dev diff --git a/docz/docs/03-demos/02-frontend/01-kaioken.md b/docz/docs/03-demos/02-frontend/01-kaioken.md index 087b92e..2770ce0 100644 --- a/docz/docs/03-demos/02-frontend/01-kaioken.md +++ b/docz/docs/03-demos/02-frontend/01-kaioken.md @@ -360,9 +360,9 @@ export default function SheetJSKaiokenAoO() { { /* error message */ !pres && !loading && ( {error.message} ) } - + - ); + ); } ``` @@ -429,9 +429,9 @@ export default function SheetJSKaiokenAoO() { {pres.Index} )) } - + - ); + ); } ``` @@ -457,7 +457,7 @@ This demo was tested in the following environments: 1) Create a new site. ```bash -npm create vite@latest sheetjs-kaioken -- --template vanilla-ts +npm create vite@latest sheetjs-kaioken -- --template vanilla-ts --no-rolldown --no-interactive cd sheetjs-kaioken npm add --save kaioken npm add --save vite-plugin-kaioken -D @@ -604,7 +604,7 @@ This demo was tested in the following environments: 1) Create a new site. ```bash -npm create vite@latest sheetjs-kaioken -- --template vanilla-ts +npm create vite@latest sheetjs-kaioken -- --template vanilla-ts --no-rolldown --no-interactive cd sheetjs-kaioken npm add --save kaioken npm add --save vite-plugin-kaioken -D diff --git a/docz/docs/03-demos/02-frontend/02-react.md b/docz/docs/03-demos/02-frontend/02-react.md index 140485e..024f3c3 100644 --- a/docz/docs/03-demos/02-frontend/02-react.md +++ b/docz/docs/03-demos/02-frontend/02-react.md @@ -341,7 +341,7 @@ This demo was tested in the following environments: 1) Create a new site: ```bash -npm create vite@latest sheetjs-react -- --template react +npm create vite@latest sheetjs-react -- --template react --no-rolldown --no-interactive ``` 2) Install the SheetJS dependency and start the dev server: @@ -845,7 +845,7 @@ This demo was tested in the following environments: 1) Create a new site: ```bash -npm create vite@latest sheetjs-react -- --template react +npm create vite@latest sheetjs-react -- --template react --no-rolldown --no-interactive ``` 2) Install the SheetJS dependency and start the dev server: diff --git a/docz/docs/03-demos/02-frontend/04-vue.md b/docz/docs/03-demos/02-frontend/04-vue.md index e6c11ff..043aa69 100644 --- a/docz/docs/03-demos/02-frontend/04-vue.md +++ b/docz/docs/03-demos/02-frontend/04-vue.md @@ -59,14 +59,15 @@ depends on the application. ### Array of Objects -Typically, some users will create a spreadsheet with source data that should be -loaded into the site. This sheet will have known columns. +Typically, users will create a spreadsheet with data that should be imported to +the site. The data sheets will typically store headers in the first row. In some +applications, the data will follow a standardized template. #### State The example [presidents sheet](https://docs.sheetjs.com/pres.xlsx) has one header row with "Name" and "Index" columns. The natural JS representation is an -object for each row, where the keys are specified in the first row: +object for each data row, where the values in the first row are used as keys: @@ -114,7 +115,8 @@ const pres = ref([]); ``` -When the spreadsheet header row is known ahead of time, row typing is possible: +`ref` is a generic method in TypeScript. If the spreadsheet header row is known +ahead of time, each row object can be typed: ```html + + +``` + +5) Start a local HTTP server: + +```bash +npx -y http-server . +``` + +Access the displayed URL (typically `http://localhost:8080`) with a web browser. + +Click the "Click here to export" button to generate `Presidents.xlsx` + +[^1]: See [`read` in "Reading Files"](/docs/api/parse-options) +[^2]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output) +[^3]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input) +[^4]: See [`writeFile` in "Writing Files"](/docs/api/write-options) \ No newline at end of file diff --git a/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md b/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md index 218b1cf..2b071ba 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md @@ -34,8 +34,8 @@ This demo was tested in the following environments: | Version | Date | |:---------|:-----------| -| `2.14.4` | 2025-05-07 | -| `1.12.3` | 2025-05-07 | +| `2.16.1` | 2025-11-15 | +| `1.12.3` | 2025-11-15 | ::: @@ -44,7 +44,7 @@ This demo was tested in the following environments: [The "Frameworks" section](/docs/getting-started/installation/frameworks) covers installation with Yarn and other package managers. -After installing the SheetJS module in a RollupJS project, `import` statements +After installing the SheetJS module in a ParcelJS project, `import` statements can load relevant parts of the library: ```js diff --git a/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md b/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md index e8a0f8a..ad30718 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md @@ -35,7 +35,7 @@ This demo was tested in the following environments: | Version | Date | |:----------|:-----------| -| `1.21.1` | 2025-06-18 | +| `1.15.2` | 2025-11-15 | ::: @@ -75,8 +75,8 @@ thread '' panicked at 'cannot access a scoped thread local variable wit This bug is known to affect versions `1.3.100`, `1.4.17`, and `1.10.6`. -This bug was fixed in version `1.21.1`. It is strongly recommended to upgrade -existing projects to use `1.21.1` or to downgrade to `1.2.246`. +This bug was fixed in version `1.12.1`. It is strongly recommended to upgrade +existing projects to use `1.12.1` or to downgrade to `1.2.246`. ::: @@ -95,17 +95,17 @@ npm init -y {`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.21.1`} +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.13.5`} {`\ -pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.21.1`} +pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.13.5`} {`\ -yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.21.1`} +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz regenerator-runtime @swc/cli @swc/core@1.13.5`} diff --git a/docz/docs/03-demos/02-frontend/19-bundler/index.md b/docz/docs/03-demos/02-frontend/19-bundler/index.md index 614151b..3bdd820 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/index.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/index.md @@ -62,7 +62,7 @@ This demo was tested in the following environments: | Version | Date | |:--------|:-----------| -| `3.8.8` | 2025-01-07 | +| `3.8.8` | 2025-11-15 | ::: @@ -149,7 +149,7 @@ writeFileXLSX(workbook, "Presidents.xlsx"); ``` -:::note pass +:::danger pass Unlike other bundlers, Snowpack requires a full page including `HEAD` element. @@ -194,7 +194,7 @@ This demo was tested in the following environments: | Version | Date | |:--------|:-----------| -| `3.8.0` | 2025-01-07 | +| `3.8.0` | 2025-11-15 | ::: diff --git a/docz/docs/03-demos/12-static/05-vitejs.md b/docz/docs/03-demos/12-static/05-vitejs.md index 0f45df9..1d06ee8 100644 --- a/docz/docs/03-demos/12-static/05-vitejs.md +++ b/docz/docs/03-demos/12-static/05-vitejs.md @@ -356,11 +356,12 @@ This demo was tested in the following environments: | ViteJS | Date | |:---------|:-----------| -| `6.2.3` | 2025-03-30 | -| `5.4.15` | 2025-03-30 | -| `4.5.10` | 2025-03-30 | -| `3.2.11` | 2025-03-30 | -| `2.9.18` | 2025-03-30 | +| `7.2.2` | 2025-11-15 | +| `6.4.1` | 2025-11-15 | +| `5.4.21` | 2025-11-15 | +| `4.5.14` | 2025-11-15 | +| `3.2.11` | 2025-11-15 | +| `2.9.18` | 2025-11-15 | ::: @@ -376,7 +377,7 @@ major version. For example, `npm create vite@3` will use ViteJS major version 3. ::: {`\ -npm create vite@5 sheetjs-vite -- --template vue-ts +npm create vite@5 sheetjs-vite -- --template vue-ts --no-rolldown --no-interactive cd sheetjs-vite npm i npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} diff --git a/docz/docs/03-demos/17-mobile/05-capacitor.md b/docz/docs/03-demos/17-mobile/05-capacitor.md index 64190e7..459a225 100644 --- a/docz/docs/03-demos/17-mobile/05-capacitor.md +++ b/docz/docs/03-demos/17-mobile/05-capacitor.md @@ -242,7 +242,7 @@ npx -y @capacitor/cli telemetry 2) Create a new Svelte project: ```bash -npm create vite@latest sheetjs-cap -- --template svelte +npm create vite@latest sheetjs-cap -- --template svelte --no-rolldown --no-interactive cd sheetjs-cap ``` diff --git a/docz/docs/03-demos/27-local/01-file.md b/docz/docs/03-demos/27-local/01-file.md index 7faff4a..4f330e1 100644 --- a/docz/docs/03-demos/27-local/01-file.md +++ b/docz/docs/03-demos/27-local/01-file.md @@ -291,7 +291,7 @@ following screenshot was taken in Chrome 126.0.6478.127: This is a browser limitation and no pure JavaScript library can work around the issue. See [Issue #3145](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145) in -the SheetJS bug tracker for more details. +the SheetJS CE bug tracker for more details. ::: @@ -466,13 +466,13 @@ This browser demo was tested in the following environments: | Browser | Date | |:-------------|:-----------| -| Chromium 137 | 2025-06-20 | +| Chromium 142 | 2025-11-15 | Some lesser-used browsers do not support File System Access API: | Browser | Date | |:-------------|:-----------| -| Safari 18.5 | 2025-06-20 | +| Safari 26.1 | 2025-11-15 | | Konqueror 22 | 2025-04-23 | | Firefox 139 | 2025-06-20 | @@ -836,4 +836,4 @@ Desktop and mobile apps have their own specific APIs covered in separate demos: [^1]: See ["Input Type" in "Reading Files"](/docs/api/parse-options#input-type) [^2]: See ["Supported Output Formats" type in "Writing Files"](/docs/api/write-options#supported-output-formats) [^3]: See ["Buffers and TypedArrays"](https://nodejs.org/api/buffer.html#buffers-and-typedarrays) in the NodeJS documentation. -[^4]: See [issue 3145 in the SheetJS bug tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145#issuecomment-11074) for more details. Special thanks to `@sjoenH`! \ No newline at end of file +[^4]: See [issue 3145 in the SheetJS CE bug tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145#issuecomment-11074) for more details. Special thanks to `@sjoenH`! \ No newline at end of file diff --git a/docz/docs/03-demos/32-extensions/41-ghidra.md b/docz/docs/03-demos/32-extensions/41-ghidra.md index b83cd18..463d819 100644 --- a/docz/docs/03-demos/32-extensions/41-ghidra.md +++ b/docz/docs/03-demos/32-extensions/41-ghidra.md @@ -28,7 +28,7 @@ This demo was tested by SheetJS users in the following deployments: | Architecture | Ghidra | Date | |:-------------|:----------|:-----------| | `darwin-x64` | `11.13.1` | 2025-04-17 | -| `darwin-arm` | `11.13.1` | 2025-03-17 | +| `darwin-arm` | `11.13.1` | 2025-10-19 | ::: @@ -255,30 +255,18 @@ Rows will be generated for each block and the final dataset will be exported. ### System Setup -0) Install Ghidra, Xcode, and Apple Numbers. +0) Install Java, Ghidra, Xcode, and Apple Numbers.
Installation Notes (click to show) -On macOS, Ghidra was installed using Homebrew: +When this demo was last tested, Java and Ghidra were installed using Homebrew: ```bash +brew install zulu@21 brew install --cask ghidra ``` -:::note pass - -Ghidra requires Java to run. If Ghidra returns `JDK 21+ (64-bit) could not be found and must be manually chosen!`: - - -```bash -brew install zulu@21 -``` - -::: - - -
1) Add the base Ghidra folder to the PATH variable. The following shell command diff --git a/docz/docs/03-demos/37-bigdata/01-stream.md b/docz/docs/03-demos/37-bigdata/01-stream.md index 0a00872..9f79c19 100644 --- a/docz/docs/03-demos/37-bigdata/01-stream.md +++ b/docz/docs/03-demos/37-bigdata/01-stream.md @@ -180,25 +180,25 @@ be reported to the Bun project for further diagnosis. This demo was tested in the following deployments: -| Node Version | Date | Node Status when tested | -|:-------------|:-----------|:------------------------| -| `0.12.18` | 2025-04-24 | End-of-Life | -| `4.9.1` | 2025-04-24 | End-of-Life | -| `6.17.1` | 2025-04-24 | End-of-Life | -| `8.17.0` | 2025-04-24 | End-of-Life | -| `10.24.1` | 2025-04-24 | End-of-Life | -| `12.22.12` | 2025-04-24 | End-of-Life | -| `14.15.5` | 2025-04-24 | End-of-Life | -| `16.20.2` | 2025-04-24 | End-of-Life | -| `18.20.8` | 2025-04-24 | Maintenance LTS | -| `20.18.0` | 2025-04-24 | Active LTS | -| `22.14.0` | 2025-04-24 | Current | +| Platform | Date | Status when tested | +|:------------------|:-----------|:-------------------| +| NodeJS `0.12.18` | 2025-11-15 | End-of-Life | +| NodeJS `4.9.1` | 2025-11-15 | End-of-Life | +| NodeJS `6.17.1` | 2025-11-15 | End-of-Life | +| NodeJS `8.17.0` | 2025-11-15 | End-of-Life | +| NodeJS `10.24.1` | 2025-11-15 | End-of-Life | +| NodeJS `12.22.12` | 2025-11-15 | End-of-Life | +| NodeJS `14.21.3` | 2025-11-15 | End-of-Life | +| NodeJS `16.20.2` | 2025-11-15 | End-of-Life | +| NodeJS `18.20.8` | 2025-11-15 | End-of-Life | +| NodeJS `20.18.0` | 2025-11-15 | Maintenance LTS | +| NodeJS `22.21.1` | 2025-11-15 | Active LTS | +| NodeJS `24.11.1` | 2025-11-15 | Current | +| BunJS `1.3.2` | 2025-11-15 | Current | While streaming methods work in End-of-Life versions of NodeJS, production deployments should upgrade to a Current or LTS version of NodeJS. -This demo was also tested against BunJS `1.2.10` on 2025-04-24. - ::: 1) Install the [NodeJS module](/docs/getting-started/installation/nodejs) diff --git a/docz/docs/06-solutions/01-input.md b/docz/docs/06-solutions/01-input.md index 1fa673f..5381758 100644 --- a/docz/docs/06-solutions/01-input.md +++ b/docz/docs/06-solutions/01-input.md @@ -29,7 +29,6 @@ var workbook = XLSX.read(data, opts); The `read` method can extract data from spreadsheet bytes stored in a JS string, "binary string", NodeJS buffer or typed array (`Uint8Array` or `ArrayBuffer`). - _Read spreadsheet bytes from a local file and extract data_ ```js @@ -38,8 +37,8 @@ var workbook = XLSX.readFile(filename, opts); The `readFile` method attempts to read a spreadsheet file at the supplied path. -The second `opts` argument is optional. ["Parsing Options"](/docs/api/parse-options) -covers the supported properties and behaviors. +The ["Reading Files"](/docs/api/parse-options) section covers the supported +properties and behaviors. :::danger pass @@ -48,7 +47,6 @@ security risk), and running `XLSX.readFile` in the browser will throw an error. Deno scripts must be invoked with `--allow-read` to read from the filesystem. - ::: #### Examples @@ -165,7 +163,6 @@ const workbook = read(Buffer.from(readFileSync(path))); - ### Example: User Submissions This example focuses on user-submitted files through a drag-and-drop event, HTML @@ -188,7 +185,6 @@ Assume `drop_dom_element` is the DOM element that will listen for changes: The event property is `e.dataTransfer`. The code snippet highlights the difference between the drag-and-drop example and the file input example: - ```js // XLSX is a global from the standalone script @@ -238,7 +234,6 @@ input_dom_element.addEventListener("change", handleFileAsync, false); https://oss.sheetjs.com/sheetjs/ demonstrates the FileReader technique. - **For maximal compatibility (IE10+)**, the `FileReader` approach is recommended: @@ -387,11 +382,9 @@ curl -X POST -F "file=@test.xlsx" http://localhost:7262/ ::: - - ### Example: Remote File This example focuses on fetching files ("Ajax" in browser parlance) using APIs @@ -587,7 +580,6 @@ other tools. ::: - @@ -731,7 +723,6 @@ var worksheet = XLSX.utils.aoa_to_sheet([ ["Array of Arrays Input"](/docs/api/utilities/array#array-of-arrays-input) describes the function and the optional `opts` argument in more detail. - _Create a worksheet from an array of JS objects_ ```js @@ -765,7 +756,6 @@ databases and query results. - ## Processing HTML Tables #### API @@ -781,8 +771,6 @@ through the rows to generate a worksheet. The `opts` argument is optional. ["HTML Table Input"](/docs/api/utilities/html#html-table-input) describes the function in more detail. - - _Create a workbook by scraping an HTML TABLE in the page_ ```js diff --git a/docz/docs/07-csf/07-features/04-comments.md b/docz/docs/07-csf/07-features/04-comments.md index ebffcaa..77044d8 100644 --- a/docz/docs/07-csf/07-features/04-comments.md +++ b/docz/docs/07-csf/07-features/04-comments.md @@ -4,6 +4,9 @@ sidebar_label: Cell Comments sidebar_position: 4 --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +
File Format Support (click to show) @@ -34,7 +37,7 @@ support Excel styled comments or Excel legacy notes. The letter R (R) marks features parsed but not written in the format. -:::note pass +:::tip pass [SheetJS Pro](https://sheetjs.com/pro) supports comment rich text and styling. @@ -43,25 +46,66 @@ The letter R (R) marks features parsed but not written in the format.
Comments and notes are cell annotations. Cells with comments or notes are marked -with a small triangle or `¬` in the upper-right corner. +with `◥` or `¬` in the upper-right corner. Excel notes are standalone text boxes with adjustable background colors and support for rich text. Historically people "replied" to comments by adding text to the end of existing comments. Excel comments are simple text boxes that allow users to enter plain text. Users -can reply to comments. +can reply to comments. The replies are typically shown in a vertical stack. -The following screenshot shows a spreadsheet with comments and a note. +#### Live Example + +The following live example shows a spreadsheet with comments and a note. - The note is associated with cell A1 (the cell with the red triangle). It has a green gradient background fill. - The comments are associated with cell A2 (the cell with the blue `¬`). There are 2 comments from different authors. A "Reply" box appears below the thread. +:::caution pass + +Excel for Mac and other software that lack full support for threaded comments +will show a fallback note that includes each reply on a separate line. + +::: + ![Excel comments and notes](pathname:///comments/types.png) -:::info pass +
+ Live Example (click to hide) + +```jsx live +function SheetJSThreadedComments() { + return ( ); +} +``` + +
+ +:::info Application Support Google Sheets "notes" do not currently support rich text or background colors. @@ -71,19 +115,18 @@ Apple Numbers supports "comments" but does not support "notes". ## Basic Structure -Cell comments are objects stored in the `c` array of cell objects. - -The comment content is split into parts based on the comment author. - -The `a` field of each comment part is the author of the comment and the `t` -field is the plain text representation. +Cell comments are stored in the `c` property of cell objects. They are expected +to be arrays of fragments objects that include text and metadata. For example, the following snippet appends a cell comment into cell `A1`: -```js + + + +```js title="Add cell comment to cell A1 in a sparse worksheet" /* get cell A1, creating an empty cell if necessary */ var cell = ws["A1"]; -if(!ws["A1"]) ws["A1"] = { t: "z" }; +if(!cell) cell = ws["A1"] = { t: "z" }; /* create comment array if it does not exist */ if(!cell.c) cell.c = []; @@ -98,6 +141,78 @@ var comment_part = { cell.c.push(comment_part); ``` + + + +:::info pass + +[`read`](/docs/api/parse-options), [`aoa_to_sheet`](/docs/api/utilities/array), +and other SheetJS methods will generate sparse worksheets by default. + +[Dense mode worksheets](/docs/csf/sheet#dense-mode) require explicit opt-in. + +::: + +```js title="Add cell comment to cell A1 in a dense worksheet" +/* get cell A1, creating an empty cell if necessary */ +var row = ws["!data"][0]; +if(!row) row = ws["!data"][0] = []; +var cell = row[0]; +if(!row[0]) cell = row[0] = { t: "z" }; + +/* create comment array if it does not exist */ +if(!cell.c) cell.c = []; + +/* create a comment part */ +var comment_part = { + a: "SheetJS", + t: "I'm a little comment, short and stout!" +}; + +/* Add comment part to the comment array */ +cell.c.push(comment_part); +``` + + + + +### Fragment Properties + +Fragments support the following properties: + +| Key | Description | +|:----|:-------------------------------------------------------------------| +| `t` | [Text](#fragment-text) | +| `a` | [Author](#fragment-author) | +| `T` | If true, fragment is a [threaded comment](#threaded-comments) part | + +#### Fragment Text + +Each fragment must include text. + +Note and comment fragment texts are concatenated to form the full text. + +[Threaded comment](#threaded-comments) fragments are visually distinct. + +:::tip pass + +SheetJS CE supports plaintext comments. + +[SheetJS Pro](https://sheetjs.com/pro) supports comment styling and rich text. + +Google Sheets and Excel threaded comments currently do not support styling. + +::: + +#### Fragment Author + +The fragment author is optional. + +Note and comment fragment authors are not displayed in Excel. + +[Threaded comment](#threaded-comments) fragment authors are displayed in the +thread in Excel. + :::note XLSB Author limits XLSB enforces a 54 character limit on the Author name. Names longer than 54 @@ -105,6 +220,46 @@ characters may cause issues with other formats. ::: +### Comment Properties + +#### Visibility + +The `hidden` property of the comment block indicates comment visibility. If set +to `true`, the comment will not be visible until users hover over the comment. + +```js title="Mark a cell comment as hidden" +if(!cell.c) cell.c = []; +// highlight-next-line +cell.c.hidden = true; +cell.c.push({a:"SheetJS", t:"This comment will be hidden"}); +``` + +
+ Live Example (click to show) + +The following demo creates a worksheet with two comments. The comment in cell A1 +will be visibile and the comment in cell A2 will be hidden. + +```jsx live +function SheetJSComments2() { + return (); +} +``` + +
+ ## Demos #### Export @@ -172,44 +327,6 @@ function SheetJSParseComments(props) { -## Visibility - -The `hidden` property of the comment block indicates comment visibility. If set -to `true`, the comment will not be visible until users hover over the comment. - -```js -if(!cell.c) cell.c = []; -// highlight-next-line -cell.c.hidden = true; -cell.c.push({a:"SheetJS", t:"This comment will be hidden"}); -``` - -
- Live Example (click to show) - -The following demo creates a worksheet with two comments. The comment in cell A1 -will be visibile and the comment in cell A2 will be hidden. - -```jsx live -function SheetJSComments2() { - return (); -} -``` - -
- ## Threaded Comments Threaded comments are plain text comment snippets with author metadata and @@ -217,7 +334,7 @@ parent references. They are supported in XLSX, XLSB, and NUMBERS files. To mark a comment as threaded, each comment part must have a true `T` property: -```js +```js title="Create a threaded comment with a reply" if(!cell.c) cell.c = []; var part1 = { @@ -237,34 +354,8 @@ var part2 = { cell.c.push({ ...part2, T: true}); ``` +:::caution pass + There is no Active Directory or Office 365 metadata associated with authors. -
- Live Example (click to hide) - -```jsx live -function SheetJSThreadedComments() { - return ( ); -} -``` - -
+::: diff --git a/docz/docs/07-csf/07-features/06-nf.md b/docz/docs/07-csf/07-features/06-nf.md index afe1667..0845de2 100644 --- a/docz/docs/07-csf/07-features/06-nf.md +++ b/docz/docs/07-csf/07-features/06-nf.md @@ -15,31 +15,31 @@ is stored as the formatted value. The formatted values can be generated from many different values and number formats. SheetJS parsers expose options to control value parsing and number format speculation. -| Formats | Basic | Storage Representation | -|:------------------|:-----:|:-----------------------| -| XLSX / XLSM | ✔ | Number Format Code | -| XLSB | ✔ | Number Format Code | -| XLS | ✔ | Number Format Code | -| XLML | ✔ | Number Format Code | -| SYLK | R | Number Format Code | -| ODS / FODS / UOS | ✔ | XML Tokens | -| NUMBERS | | Binary encoding | -| WK1 | + | Fixed set of formats | -| WK3 / WK4 | | Binary encoding | -| WKS Lotus | + | Fixed set of formats | -| WKS Works | + | Fixed set of formats | -| WQ1 | + | Fixed set of formats | -| WQ2 | | Binary encoding | -| WB1 / WB2 / WB3 | | Binary encoding | -| QPW | + | Binary encoding | -| DBF | | Implied by field types | -| HTML | ! | Special override | -| CSV | * | N/A | -| PRN | * | N/A | -| DIF | * | N/A | -| RTF | * | N/A | +| Formats | Basic | Storage Representation | +|:------------------|:-----:|:--------------------------| +| XLSX / XLSM | ✔ | Number Format Code | +| XLSB | ✔ | Number Format Code | +| XLS | ✔ | Number Format Code | +| XLML | ✔ | Number Format Code | +| SYLK | R | Number Format Code | +| ODS / FODS / UOS | ✔ | XML Tokens | +| NUMBERS | | Binary encoding | +| WK1 | + | Fixed set of formats | +| WK3 / WK4 | | Binary encoding | +| WKS Lotus | + | Fixed set of formats | +| WKS Works | + | Fixed set of formats | +| WQ1 | + | Fixed set of formats | +| WQ2 | | Binary encoding | +| WB1 / WB2 / WB3 | | Binary encoding | +| QPW | + | Binary encoding | +| DBF | | Inferred from field types | +| HTML | ! | Special override | +| CSV | * | N/A | +| PRN | * | N/A | +| DIF | * | N/A | +| RTF | * | N/A | -(+) mark formats with limited support. The QPW (Quattro Pro Workbooks) parser +Plus symbols (+) mark formats with limited support. The QPW (Quattro Pro) parser supports the built-in date and built-in time formats but does not support custom number formats. [Date and Time support](/docs/csf/features/dates) in modern Excel formats requires limited number format support to distinguish date diff --git a/docz/docs/08-api/03-parse-options.md b/docz/docs/08-api/03-parse-options.md index ea4d676..1d40e66 100644 --- a/docz/docs/08-api/03-parse-options.md +++ b/docz/docs/08-api/03-parse-options.md @@ -5,7 +5,7 @@ hide_table_of_contents: true --- The main SheetJS method for reading files is `read`. It expects developers to -supply the actual data in a supported representation. +supply the actual data in a [supported representation](#input-type). The `readFile` helper method accepts a filename and tries to read the specified file using standard APIs. *It does not work in web browsers!* @@ -38,64 +38,130 @@ includes additional instructions for non-standard use cases. ::: +:::tip pass + +The SheetJS file format import codecs focus on raw data. Not all codecs support +all features. Features not described in the documentation may not be extracted. + +[SheetJS Pro](https://sheetjs.com/pro) offers support for additional features, +including styling, images, graphs, and PivotTables. + +::: + ## Parsing Options The read functions accept an options argument: -| Option Name | Default | Description | -|:------------|:--------|:-----------------------------------------------------| -|`type` | | [Input data representation](#input-type) | -|`raw` | `false` | If true, plain text parsing will not parse values ** | -|`dense` | `false` | If true, use a [dense sheet representation](#dense) | -|`codepage` | | If specified, use code page when appropriate ** | -|`cellFormula`| `true` | Save [formulae to the `.f` field](#formulae) | -|`cellHTML` | `true` | Parse rich text and save HTML to the `.h` field | -|`cellNF` | `false` | Save number format string to the `.z` field | -|`cellStyles` | `false` | Save style/theme info to the `.s` field | -|`cellText` | `true` | Generated formatted text to the `.w` field | -|`cellDates` | `false` | Store dates as type `d` (default is `n`) | -|`dateNF` | | If specified, use the string for date code 14 ** | -|`sheetStubs` | `false` | Create cell objects of type `z` for stub cells | -|`sheetRows` | `0` | If >0, read the [specified number of rows](#range) | -|`bookDeps` | `false` | If true, parse calculation chains | -|`bookFiles` | `false` | If true, add raw files to book object ** | -|`bookProps` | `false` | If true, only parse enough to get book metadata ** | -|`bookSheets` | `false` | If true, only parse enough to get the sheet names | -|`bookVBA` | `false` | If true, generate [VBA blob](#vba) | -|`password` | `""` | If defined and file is encrypted, use password ** | -|`WTF` | `false` | If true, throw errors on unexpected file features ** | -|`sheets` | | If specified, only parse specified sheets ** | -|`nodim` | `false` | If true, calculate [worksheet ranges](#range) | -|`PRN` | `false` | If true, allow parsing of PRN files ** | -|`xlfn` | `false` | If true, [preserve prefixes](#formulae) in formulae | -|`FS` | | DSV Field Separator override | -|`UTC` | `true` | If explicitly false, parse text dates in local time | +| Option Name | Default | Description | +|:--------------|:--------|:---------------------------------------------------| +| `type` | | [Input data representation](#input-type) | +| `raw` | `false` | Disable [value parsing in plaintext formats](#raw) | +| `dense` | `false` | If true, [generate dense worksheets](#dense) | +| `codepage` | | Use specified [code page encoding](#codepage) | +| `cellFormula` | `true` | Save [formulae to the `f` field](#formulae) | +| `cellHTML` | `true` | Parse text and [save HTML to the `h` field](#html) | +| `cellNF` | `false` | Save [number format to the `z` field](#text) | +| `cellStyles` | `false` | Save [style/theme info to the `s` field](#style) | +| `cellText` | `true` | Save [formatted text to the `w` field](#text) | +| `cellDates` | `false` | [Generate proper date (type `d`) cells](#dates) | +| `dateNF` | | If specified, [override date code 14](#dates) | +| `sheetStubs` | `false` | [Create cells of type `z` for stub cells](#stubs) | +| `sheetRows` | `0` | If >0, read the [specified number of rows](#range) | +| `bookDeps` | `false` | If true, parse calculation chains | +| `bookFiles` | `false` | Add [raw files](#files) to book object | +| `bookProps` | `false` | If true, [only parse book metadata](#metadata) | +| `bookSheets` | `false` | If true, [only parse sheet names](#metadata) | +| `bookVBA` | `false` | If true, generate [VBA blob](#vba) | +| `password` | `""` | If specified, [decrypt workbook](#password) | +| `WTF` | `false` | [Do not suppress worksheet parsing errors](#wtf) | +| `sheets` | | Only parse [specified sheets](#sheets) | +| `nodim` | `false` | If true, calculate [worksheet ranges](#range) | +| `PRN` | `false` | If true, [allow parsing of PRN files](#prn) | +| `xlfn` | `false` | Use [raw formula function names](#formulae) | +| `FS` | | [DSV Field Separator override](#dsv) | +| `UTC` | `true` | Parse [text dates and times using UTC](#tz) | -- Even if `cellNF` is false, formatted text will be generated and saved to `.w` -- In some cases, sheets may be parsed even if `bookSheets` is false. -- Excel aggressively tries to interpret values from CSV and other plain text. - This leads to surprising behavior! The `raw` option suppresses value parsing. -- `bookSheets` and `bookProps` combine to give both sets of information -- `Deps` will be an empty object if `bookDeps` is false -- `bookFiles` behavior depends on file type: - * `keys` array (paths in the ZIP) for ZIP-based formats - * `files` hash (mapping paths to objects representing the files) for ZIP - * `cfb` object for formats using CFB containers -- By default all worksheets are parsed. `sheets` restricts based on input type: - * number: zero-based index of worksheet to parse (`0` is first worksheet) - * string: name of worksheet to parse (case insensitive) - * array of numbers and strings to select multiple worksheets. -- `codepage` is applied to BIFF2 - BIFF5 files without `CodePage` records and to - CSV files without BOM in `type:"binary"`. BIFF8 XLS always defaults to 1200. -- `PRN` affects parsing of text files without a common delimiter character. -- Currently only XOR encryption is supported. Unsupported error will be thrown - for files employing other encryption methods. -- `WTF` is mainly for development. By default, the parser will suppress read - errors on single worksheets, allowing you to read from the worksheets that do - parse properly. Setting `WTF:true` forces those errors to be thrown. -- `UTC` applies to CSV, Text and HTML formats. When explicitly set to `false`, - the parsers will assume the files are specified in local time. By default, as - is the case for other file formats, dates and times are interpreted in UTC. +### Cell-Level Options + +#### Dates + +By default, for consistency with spreadsheet applications, date cells are stored +as numeric cells (type `n`) with special number formats. If `cellDates` is +enabled, date codes are converted to proper Date objects. + +Excel file formats (including XLSX, XLSB, and XLS) support a locale-specific +date format, typically stored as date code 14 or the string `m/d/yy`. The +formatted text for some cells will change based on the computer locale. SheetJS +parsers use the `en-US` form by default. If the `dateNF` option is set, that +number format string will be used. + +["Dates and Times"](/docs/csf/features/dates) covers features in more detail. + +#### Formulae + +For some file formats, the `cellFormula` option must be explicitly enabled to +ensure that formulae are extracted. + +Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the +user. By default, the file parsers will strip `_xlfn.` and similar prefixes. +If the `xlfn` option is enabled, the prefixes will be preserved. + +[The "Formulae" docs](/docs/csf/features/formulae#prefixed-future-functions) +covers this in more detail. + +#### Formatted Text {#text} + +Many common spreadsheet formats (including XLSX, XLSB, and XLS) store numeric +values and number formats. Applications are expected to use the number formats +to display currency strings, dates, and other values. + +Under the hood, parsers use the [SSF Number Formatter](/docs/constellation/ssf) +library to generated formatted text. + +By default, formatted text is generated. If the `cellText` option is false, +formatted text will not be written. + +By default, cell number formats are not preserved. If the `cellNF` option is +enabled, number format strings will be saved to the `z` field of cell objects. + +["Number Formats"](/docs/csf/features/nf) covers the features in more detail. + +:::note pass + +Even if `cellNF` is false, formatted text will be generated and saved to `w`. + +::: + +#### Text and Cell Styling {#style} + +By default, SheetJS CE parsers focus on data extraction. + +If the `cellStyles` option is `true`, other styling metadata including +[row](/docs/csf/features/rowprops) and [column](/docs/csf/features/colprops) +properties will be parsed. + +:::tip pass + +[SheetJS Pro](https://sheetjs.com/pro) offers cell / text styling, conditional +formatting and additional styling options. + +::: + +#### HTML Formatted Text {#html} + +Spreadsheet applications support a limited form of rich text styling. + +If the `cellHTML` option is `true`, some file parsers will attempt to translate +the rich text to standard HTML with inner tags for bold text and other styles. + +:::tip pass + +[SheetJS Pro](https://sheetjs.com/pro) offers additional styling options, +conversions for all supported file formats, and whole-worsheet HTML generation. + +::: + +### Sheet-Level Options #### Dense @@ -130,17 +196,16 @@ The `nodim` option instructs the parser to ignore self-reported ranges and use the actual cells in the worksheet to determine the range. This addresses known issues with non-compliant third-party exporters. -#### Formulae +#### Stubs -For some file formats, the `cellFormula` option must be explicitly enabled to -ensure that formulae are extracted. +Some file formats, including XLSX and XLS, can specify cells without cell data. +For example, cells covered by a [merged cell block](/docs/csf/features/merges) +are technically invalid but files may include metadata. -Newer Excel functions are serialized with the `_xlfn.` prefix, hidden from the -user. SheetJS will strip `_xlfn.` normally. The `xlfn` option preserves them. -[The "Formulae" docs](/docs/csf/features/formulae#prefixed-future-functions) -covers this in more detail. +By default, the cells are skipped. If the `sheetStubs` option is `true`, these +cells will be parsed as [stub cells](/docs/csf/cell#cell-types) -["Formulae"](/docs/csf/features/formulae) covers the features in more detail. +### Book-Level Options #### VBA @@ -160,18 +225,166 @@ new blob from the XLS CFB container that works in XLSM and XLSB files. +#### Workbook Metadata {#metadata} + +By default, the data from each worksheet is parsed. + +If any of the following options are passed, parsers will not parse sheet data. +They will parse enough of the workbook to extract the requested information. + +| Option | Extracted Data | +|:-------------|:--------------------| +| `bookProps` | Workbook properties | +| `bookSheets` | Worksheet names | + +The options apply to XLSX, XLSB, XLS and XLML parsers. + +#### Worksheets {#sheets} + +By default, all worksheets are parsed. The `sheets` option limits which sheets +are parsed. + +If the `sheets` option is a number, the number is interpreted as a zero-based +index. For example, `sheets: 2` instructs the parser to read the third sheet. + +If the `sheets` option is text, the string is interpreted as a worksheet name. +The name is case-insensitive. `sheets: "Sheet1"` instructs the parser to read +the worksheet named "Sheet1". + +If the `sheets` option is an array of numbers and text, each worksheets will +be parsed. `sheets: [2, "Sheet1"]` instructs the parser to read the third sheet +and the sheet named "Sheet1". If the third worksheet is coincidentally named +"Sheet1", only one worksheet will be parsed + +### File-Level Options + +#### Password Protection {#password} + +SheetJS CE currently supports XOR encryption in XLS files. Errors will be thrown +when trying to parse files using unsupported encryption methods. + +:::tip pass + +[SheetJS Pro](https://sheetjs.com/pro) offers support for additional encryption +schemes, including the AES-CBC schemes used in XLSX / XLSM / XLSB files and the +RC4 schemes used in newer XLS files. + +::: + +#### Lotus Formatted Text (PRN) {#prn} + +Lotus Formatted Text (`PRN`) worksheets are plain text files that do not include +delimiter characters. Each cell in a column has the same width. + +If the `PRN` option is set, the plaintext parser will attempt to parse some +plaintext files as if they follow the `PRN` format. + +:::note pass + +If the `PRN` option is set, text files that do not include commas or semicolons +or other common delimiters may not be parsed as expected. + +This option should not be enabled unless it is known that the file was exported +from Lotus 1-2-3 or from Excel using the "Lotus Formatted Text (`PRN`)" format. + +::: + +#### Value Parsing {#raw} + +Spreadsheet software including Excel aggressively try to interpret values from +CSV and other plain text. This leads to surprising behavior[^1]! + +If the `raw` option is true, value parsing will be suppressed. All cells values +are treated as strings. + +The `raw` option affects the following formats: HTML, CSV, PRN, DIF, RTF. + +The `raw` option does not affect XLSX, XLSB, XLS and other file formats that +support explicit value typing. + +:::note pass + +See [Issue #3331](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145) in the +SheetJS CE bug tracker for more details. + +::: + +#### Code Page Encoding {#codepage} + +Spreadsheet applications support a number of legacy encodings. Plaintext files +will appear different when opened in different computers in different regions. + +By default, the parsers use the most common "English (United States)" encodings. +The `codepage` option controls the encoding in BIFF2 - BIFF5 XLS files without +`CodePage` records, some legacy formats including DBF, and in CSV files without +BOM in `type: "binary"`. BIFF8 XLS always defaults to 1200. + +The `codepage` support library is not guaranteed to be loaded by default. The +["Installation"](/docs/getting-started/installation/) section describes how to +install and load the support library. + +See ["Legacy Codepages"](/docs/constellation/codepage) for more details. + +#### Date Processing {#tz} + +Plaintext formats may include date and time values without timezone info. The +time `12:30 AM` is ambiguous. + +In the wild, there are two popular approaches: + +A) Spreadsheet software typically interpret time values using local timezones. +When opening a file in New York, `12:30 AM` will be parsed as `12:30 AM ET`. +When opening a file in Los Angeles, the time will be parsed as `12:30 AM PT`. + +B) APIs use [UTC](https://en.wikipedia.org/wiki/Coordinated_Universal_Time), the +most popular global time standard. `12:30 AM` will be parsed as the absolute +moment in time corresponding to `8:30 PM EDT` or `7:30 PM EST`. + +By default, the parsers assume files are specified in UTC. When the `UTC` option +is explicitly set to `false`, dates and times are interpreted in timezone of the +web browser or JavaScript engine. + +#### Delimiter-Separated Values {#dsv} + +The plaintext parser applies a number of heuristics to determine if files are +CSV (fields separated by commas), TSV (fields separated by tabs), PSV (fields +separated by `|`) or SSV (fields separated by `;`). The heuristics are based on +the presence of characters not in a double-quoted value. + +The `FS` option instructs the parser to use the specified delimiter if multiple +delimiter characters are in the text. This bypasses the default heuristics. + +#### Internal Files {#files} + +Some file formats are structured as larger containers that include sub-files. +For example, XLSX files are ZIP files with XML sub-files. + +If the `bookFiles` option is `true`, each sub-file will be preserved in the +workbook. The behavior depends on file type: + +- `keys` array (paths in the ZIP) for ZIP-based formats +- `files` hash (mapping paths to objects representing the files) for ZIP +- `cfb` object for formats using CFB containers + +#### Parsing Errors {#wtf} + +By default, the workbook parser will suppress errors when parsing worksheets. +This ensures the valid worksheets from a multi-sheet workbook are parsed. + +If the `WTF` option is enabled, the errors will not be suppressed. + ### Input Type The `type` parameter for `read` controls how data is interpreted: -| `type` | expected input | -|:-----------|:----------------------------------------------------------------| -| `"base64"` | string: Base64 encoding of the file | -| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | -| `"string"` | string: JS string (only appropriate for UTF-8 text formats) | -| `"buffer"` | nodejs Buffer | -| `"array"` | array: array of 8-bit unsigned integers (byte `n` is `data[n]`) | -| `"file"` | string: path of file that will be read (nodejs only) | +| `type` | expected input | +|:---------|:----------------------------------------------------------------| +| `base64` | string: Base64 encoding of the file | +| `binary` | string: binary string (byte `n` is `data.charCodeAt(n)`) | +| `string` | string: JS string (only appropriate for UTF-8 text formats) | +| `buffer` | nodejs Buffer | +| `array` | array: array of 8-bit unsigned integers (byte `n` is `data[n]`) | +| `file` | string: path of file that will be read (nodejs only) | Some common types are automatically deduced from the data input type, including NodeJS `Buffer` objects, `Uint8Array` and `ArrayBuffer` objects, and arrays of @@ -246,3 +459,6 @@ were CSV or TSV. SheetJS attempts to replicate that behavior. +[^1]: The gene [`SEPT1`](https://en.wikipedia.org/wiki/SEPTIN1) was renamed to +`SEPTIN1` to avoid Excel value interpretations: the string `SEPT1` is parsed as +the date "September 1". \ No newline at end of file diff --git a/docz/docs/08-api/05-write-options.md b/docz/docs/08-api/05-write-options.md index 9c644e0..8ab8074 100644 --- a/docz/docs/08-api/05-write-options.md +++ b/docz/docs/08-api/05-write-options.md @@ -9,12 +9,13 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; -The main SheetJS method for writing workbooks is `write`. Scripts receive common -[JavaScript data representations](#output-type) and are expected to write or -share files using platform-specific APIs. +The main SheetJS method for writing workbooks is `write`. It accepts a SheetJS +[workbook object](/docs/csf/book) and returns the file data stored in common +[JavaScript data representations](#output-type). Scripts calling `write` are +expected to write or share files using platform-specific APIs. The `writeFile` helper method accepts a filename and tries to write to a local -file using [standard APIs](/docs/demos/local/file). +file using [standard local file APIs](/docs/demos/local/file). **Export a SheetJS workbook object in a specified file format** @@ -24,9 +25,9 @@ var file_data = XLSX.write(wb, opts); `write` attempts to write the workbook `wb` and return the file. -The `options` argument is required. It must specify -- [`bookType`](#supported-output-formats) (file format of the exported file) -- [`type`](#output-type) (return value type) +The `options` argument is required. It must specify +- [`bookType`](#bookType): file format of the exported file +- [`type`](#output-type): return value type **Export a SheetJS workbook object and attempt to write a local file** @@ -39,17 +40,18 @@ XLSX.writeFile(wb, filename, options); In browser-based environments, it will attempt to force a client-side download. It also supports NodeJS, ExtendScript applications, and Chromium extensions. +The `options` argument is optional. + If `options` is omitted or if `bookType` is missing from the `options` object, -the output file format will be deduced from the filename extension. +the output file format will be [inferred from the filename](#extension). **Special functions for exporting data in the XLSX format** ```js -// limited form of `write` +/* `write` (XLSX only) */ var file_data = XLSX.writeXLSX(wb, options); - -// limited form of `writeFile` +/* `writeFile` (XLSX only) */ XLSX.writeFileXLSX(wb, filename, options); ``` @@ -60,111 +62,357 @@ For websites that exclusively export to XLSX, these functions can reduce the size of the production site. The general `write` and `writeFile` functions are more appropriate when exporting to XLS or XLSB or other formats. -
NodeJS-specific methods (click to show) **Export a workbook and attempt to write a local file using `fs.writeFile`** ```js -// callback equivalent of `XLSX.writeFile` +/* callback equivalent of `XLSX.writeFile(wb, filename)` */ XLSX.writeFileAsync(filename, wb, cb); -// callback equivalent with options argument +/* callback equivalent of `XLSX.writeFile(wb, filename, options)` */ XLSX.writeFileAsync(filename, wb, options, cb); ``` - `writeFileAsync` attempts to write `wb` to `filename` and invoke the callback `cb` on completion. When an `options` object is specified, it is expected to be the third argument. -This method only works in NodeJS and uses `fs.writeFile` under the hood. +This method only works in NodeJS. It uses `fs.writeFile` under the hood.
:::note Recommendation -`writeFile` wraps a number of export techniques, making it suitable for browser -downloads, NodeJS, ExtendScript apps, and Chromium extensions. It does not work -in other environments with more advanced export methods. +`writeFile` wraps a number of export techniques, making it suitable for web +browsers, [Photoshop and InDesign](/docs/demos/extensions/extendscript), and +server-side platforms including NodeJS. It does not work in other environments +with more advanced export methods. -The `write` method returns raw bytes or strings that can be exported in -[Desktop apps](/docs/demos/desktop/) , [Mobile apps](/docs/demos/mobile) , and -[Servers](/docs/demos/net/server). +`write` returns raw bytes or strings that can be exported with platform-specific +APIs in [Desktop apps](/docs/demos/desktop), [Mobile apps](/docs/demos/mobile), +[Servers](/docs/demos/net/server), and [extensions](/docs/demos/extensions). The [demos](/docs/demos) preferentially use `writeFile`. When `writeFile` is not supported, the demos show file creation using `write` and platform APIs. ::: +:::tip pass + +The SheetJS file format export codecs focus on raw data. Not all codecs support +all features. Features not described in the documentation may not be serialized. + +[SheetJS Pro](https://sheetjs.com/pro) offers support for additional features, +including styling, images, graphs, and PivotTables. + +::: + ## Writing Options The write functions accept an options argument: -| Option Name | Default | Description | -| :---------- | -------: | :------------------------------------------------- | -|`type` | | Output data encoding (see Output Type below) | -|`cellDates` | `false` | Store dates as type `d` (default is `n`) | -|`cellStyles` | `false` | Save style/theme info to the `.s` field | -|`codepage` | | If specified, use code page when appropriate ** | -|`bookSST` | `false` | Generate Shared String Table ** | -|`bookType` | `"xlsx"` | Type of Workbook (see below for supported formats) | -|`bookVBA` | | Add VBA blob from workbook object to the file ** | -|`WTF` | `false` | If true, throw errors on unexpected features ** | -|`sheet` | `""` | Name of Worksheet for single-sheet formats ** | -|`compression`| `false` | Use ZIP compression for ZIP-based formats ** | -|`Props` | | Override workbook properties when writing ** | -|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** | -|`ignoreEC` | `true` | Suppress "number as text" errors ** | -|`numbers` | | Payload for NUMBERS export ** | -|`FS` | `","` | "Field Separator" delimiter between fields ** | -|`RS` | `"\n"` | "Record Separator" delimiter between rows ** | +| Option Name | Default | Description | +|:--------------|:---------|:---------------------------------------------------| +| `type` | | [Output data encoding](#output-type) | +| `cellDates` | `false` | Convert [numeric date codes to strings](#dates) | +| `cellStyles` | `false` | Export [style/theme info](#style) | +| `codepage` | | Use specified [code page encoding](#codepage) | +| `bookSST` | `false` | Generate [Shared String Table](#sst) | +| `bookType` | `"xlsx"` | [Type of Workbook](#supported-output-formats) | +| `bookVBA` | | [Add VBA blob from workbook object](#vba) | +| `WTF` | `false` | [Do not suppress warnings and errors](#wtf) | +| `sheet` | `""` | [Export the named sheet](#sheet) | +| `compression` | `false` | [Try to reduce file size](#compression) | +| `Props` | | Override [workbook properties](#props) | +| `themeXLSX` | | Override [theme XML for XLSX/XLSB/XLSM](#theme) | +| `ignoreEC` | `true` | [Suppress "number as text" errors](#ec) | +| `numbers` | | [Payload for NUMBERS export](#numbers) | +| `FS` | `","` | [Field Separator](#dsv) for CSV and Text exports | +| `RS` | `"\n"` | [Record Separator](#dsv) for CSV and Text exports | -- `bookSST` is slower and more memory intensive, but has better compatibility - with older versions of iOS Numbers -- The raw data is the only thing guaranteed to be saved. Features not described - in this README may not be serialized. -- `cellDates` only applies to XLSX output and is not guaranteed to work with - third-party readers. Excel itself does not usually write cells with type `d` - so non-Excel tools may ignore the data or error in the presence of dates. -- `codepage` is applied to legacy formats including DBF. Characters missing - from the encoding will be replaced with underscore characters (`_`). -- `Props` is an object mirroring the workbook `Props` field. See the table from - the [Workbook File Properties](/docs/csf/book#file-properties) section. -- if specified, the string from `themeXLSX` will be saved as the primary theme - for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP) -- Due to a bug in the program, some features like "Text to Columns" will crash - Excel on worksheets where error conditions are ignored. The writer will mark - files to ignore the error by default. Set `ignoreEC` to `false` to suppress. -- `FS` and `RS` apply to CSV and Text output formats. The options are discussed - in ["CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) -- `bookVBA` only applies to supported formats. ["VBA"](/docs/csf/features/vba) - section explains the feature in more detail. -- `WTF` is mainly for development. +## Supported Output Formats + + + +For broad compatibility with third-party tools, SheetJS CE supports many output +formats. The writer will select the file type based on the `bookType` option: + +| `bookType` | extension | sheets | Description | +|:-----------|:-----------|:-------|:--------------------------------| +| `xlsx` | `.xlsx` | multi | Excel 2007+ XML Format | +| `xlsm` | `.xlsm` | multi | Excel 2007+ Macro XML Format | +| `xlsb` | `.xlsb` | multi | Excel 2007+ Binary Format | +| `biff8` | `.xls` | multi | Excel 97-2004 Workbook Format | +| `biff5` | `.xls` | multi | Excel 5.0/95 Workbook Format | +| `biff4` | `.xls` | single | Excel 4.0 Worksheet Format | +| `biff3` | `.xls` | single | Excel 3.0 Worksheet Format | +| `biff2` | `.xls` | single | Excel 2.0 Worksheet Format | +| `xlml` | `.xls` | multi | Excel 2003-2004 (SpreadsheetML) | +| `numbers` | `.numbers` | multi | Numbers 3.0+ Spreadsheet | +| `ods` | `.ods` | multi | OpenDocument Spreadsheet | +| `fods` | `.fods` | multi | Flat OpenDocument Spreadsheet | +| `wk3` | `.wk3` | multi | Lotus Workbook (WK3) | +| `csv` | `.csv` | single | Comma Separated Values | +| `txt` | `.txt` | single | UTF-16 Unicode Text (TXT) | +| `sylk` | `.sylk` | single | Symbolic Link (SYLK) | +| `html` | `.html` | single | HTML Document | +| `dif` | `.dif` | single | Data Interchange Format (DIF) | +| `dbf` | `.dbf` | single | dBASE II + VFP Extensions (DBF) | +| `wk1` | `.wk1` | single | Lotus Worksheet (WK1) | +| `rtf` | `.rtf` | single | Rich Text Format (RTF) | +| `prn` | `.prn` | single | Lotus Formatted Text | +| `eth` | `.eth` | single | Ethercalc Record Format (ETH) | + +If the output format supports multiple worksheets, the workbook writer will try +to export each worksheet. If the format only supports one worksheet, the writer +will export the first worksheet. If the [`sheet` option](#sheet) is a string, +the writer will use the named sheet. + +#### Output Format inference from File Extension {#extension} + +`writeFile` will automatically guess the output file format based on the file +extension if `bookType` is not specified. + +| extension | Description | +|:-----------|:--------------------------------| +| `.csv` | Comma Separated Values | +| `.dbf` | dBASE II + VFP Extensions (DBF) | +| `.dif` | Data Interchange Format (DIF) | +| `.eth` | Ethercalc Record Format (ETH) | +| `.fods` | Flat OpenDocument Spreadsheet | +| `.html` | HTML Document | +| `.numbers` | Numbers 3.0+ Spreadsheet | +| `.ods` | OpenDocument Spreadsheet | +| `.prn` | Lotus Formatted Text | +| `.rtf` | Rich Text Format (RTF) | +| `.sylk` | Symbolic Link (SYLK) | +| `.txt` | UTF-16 Unicode Text (TXT) | +| `.wk1` | Lotus Worksheet (WK1) | +| `.wk3` | Lotus Workbook (WK3) | +| `.xls` | Excel 97-2004 Workbook Format | +| `.xlsb` | Excel 2007+ Binary Format | +| `.xlsm` | Excel 2007+ Macro XML Format | +| `.xlsx` | Excel 2007+ XML Format | + +## Output Type + +The `type` option specifies the JS form of the output: + +| `type` | output | +|----------|-----------------------------------------------------------------| +| `base64` | string: Base64 encoding of the file | +| `binary` | string: binary string (byte `n` is `data.charCodeAt(n)`) | +| `string` | string: JS string (not compatible with binary formats) | +| `buffer` | NodeJS `Buffer` or `Uint8Array` | +| `array` | `ArrayBuffer` or array of 8-bit unsigned int | +| `file` | (attempt to download a file) | + +:::note pass + +For compatibility with Excel, `csv` output will always include the UTF-8 byte +order mark ("BOM"). + +The raw [`sheet_to_csv` method](/docs/api/utilities/csv#csv-output) will return +JavaScript strings without the UTF-8 BOM. + +::: + +## Other Options + +### Cell-Level Options + +#### Dates + +Plaintext files store dates using formatted strings. XLS and most Excel file +formats store dates using numeric date codes. + +XLSX and ODS/FODS support both numeric date codes and ISO 8601 date strings. + +By default, when both numeric date codes and date strings are supported, the +writers will export date codes. Date cells (type `d`) will be converted to +numeric cells. + +If the `cellDates` option is set, writers will export date strings. If number +formats include [date tokens](/docs/csf/features/nf#dates-and-times), numeric +cells (type `n`) will be converted to date cells. + +:::caution pass + +Generated files are not guaranteed to work with third-party spreadsheet readers! +Third-party tools may ignore cells or reject files that use proper date cells. + +::: + +["Dates and Times"](/docs/csf/features/dates) covers features in more detail. + +#### Text and Cell Styling {#style} + +By default, SheetJS CE writers focus on data preservation. + +If the `cellStyles` option is `true`, other styling metadata including +[row](/docs/csf/features/rowprops) and [column](/docs/csf/features/colprops) +will be exported. + +:::tip pass + +[SheetJS Pro](https://sheetjs.com/pro) offers cell / text styling, conditional +formatting and additional styling options. + +::: + +### Sheet-Level Options + +#### Error Checking {#ec} + +By default, Excel warns users when creating text cells when the text could be +parsed as a number. People and software systems commonly use text to store US +ZIP Codes, as many ZIP Codes in New Jersey start with "0". + +By default, SheetJS writers add special marks to instruct Excel not to elicit +warnings on cells containing text that look like numbers. + +Due to a bug in Excel, "Text to Columns" and other features may lead to crashes +in files where error conditions are ignored. If the `ignoreEC` option is +explicitly set to `false`, SheetJS writers will not add the offending marks. + +### Book-Level Options + +#### VBA + +When exporting to file formats that support VBA (XLSX, XLSB, XLS), macros are +not guaranteed to be exported by default. The `bookVBA` option should be set +to a truthy value (`true` or `1`). + +The ["VBA"](/docs/csf/features/vba) section explains the feature in more detail. + +#### Workbook Properties {#props} + +When exporting to a file format that supports workbook properties, the SheetJS +export codecs will look in the workbook object for file properties. + +If the `Props` option is specified, the export codecs will ignore properties +from the workbook object. + +The ["File Properties"](/docs/csf/features/props) section lists the supported +file properties. + +### File-Level Options + +#### Compression + +XLSX, XLSB, NUMBERS, and ODS files use ZIP containers. The ZIP container format +supports different levels of compression. Spreadsheet software typically use +compression when exporting files. + +By default, SheetJS writers optimize for speed. Exports are faster but the +generated files are larger. + +If the `compression` option is set, writers will optimize for file size. Exports +are smaller but will take more time. + +#### Target Sheet {#sheet} + +Some output formats support multiple worksheets. By default, the SheetJS export +codecs will export all worksheets. + +Other output formats, including CSV and legacy Excel and Lotus worksheet files, +only support one worksheet. By default, the SheetJS export codecs will use the +first worksheet from the workbook. + +If the `sheet` option is set to the name of a valid worksheet in the workbook, +the SheetJS writers will use the named sheet even if it is not the first sheet. + +#### Shared String Table (SST) {#sst} + +XLSX, XLS, and XLSB can store text cells in two ways. + +By default, the writers use "inline" strings. The content of each text cell is +stored in the cell representation. This approach is conceptually simple, but it +uses features that may not be supported in iOS Numbers and other apps. + +If the `bookSST` option is set, writers use the "shared string table" (SST) +feature. A separate lookup table houses each text string and cells store indices +into the SST. Multiple cells can point to the same SST entry. + +Exporting with SST is typically slower and more memory intensive, but the files +may be smaller and have better compatibility with third-party software. + +#### Delimiter-Separated Values {#dsv} + +The SheetJS CSV writer uses commas to separate fields within a row and adds line +separators between rows. + +The characters used to separate fields and rows can be controlled through the +`FS` ("field separator") and `RS` ("row separator") options. + +["CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) discusses +the options in more detail. + +#### Code Page Encoding {#codepage} + +Spreadsheet applications support a number of legacy encodings. Plaintext files +will appear different when opened in different computers in different regions. + +By default, the writers use the most common "English (United States)" encodings. +The `codepage` option controls the encoding in BIFF2 - BIFF5 XLS files without +`CodePage` records, some legacy formats including DBF, and in CSV files without +BOM in `type: "binary"`. + +Characters missing from the specified encoding will be replaced with underscore +characters (`_`). + +The `codepage` support library is not guaranteed to be loaded by default. The +["Installation"](/docs/getting-started/installation/) section describes how to +install and load the support library. + +See ["Legacy Codepages"](/docs/constellation/codepage) for more details. + +#### XLSX and XLSB Theme {#theme} + +By default, the SheetJS XLSX and XLSB output codecs use a predetermined theme. +This simplifies [column widths](/docs/csf/features/colprops#column-widths) and +other features that depend on font metrics. + +If the `themeXLSX` option is a string, the XLSB and XLSX codecs will suppress +the default theme. The default theme `xl/theme/theme1.xml` will be overridden. + +#### Writing Errors {#wtf} + +If the `WTF` option is enabled, workbook writers will show warnings and errors +when workbooks use features that may be considered unsafe. For example, some +file features are only supported in specific versions of Excel. + +#### NUMBERS Exports {#numbers}
- Exporting NUMBERS files (click to show) + Rationale (click to hide) -The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl` -scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS -use, while `xlsx.zahl.mjs` is suitable for ESM. +Apple Numbers has broken backwards compatibility many times over the years. +Files generated by older versions of Numbers are not guaranteed to work with +newer versions of Numbers or third-party tools. -Adding NUMBERS export support involves two steps: +The NUMBERS exporter starts from a working file and rewrites the data blocks. +This ensures exports still work -1) Load the `xlsx.zahl` script +The current design allows for updating the base file without disrupting the rest +of the library. -2) Pass the payload into the `numbers` option to `write` or `writeFile`. +
+ +The `numbers` option is required for exporting NUMBERS files. It is expected to +be a Base64 string that encodes a valid Numbers file. The supplementary +`xlsx.zahl` scripts include the required string. - +

{"https://cdn.sheetjs.com/xlsx-" + current + "/package/dist/xlsx.zahl.js"} is the URL for {current}

-{`\ -\n\ -\n\ +{`\ +\n\ \n\ \n\ \n\ -`} +`}
@@ -250,67 +498,3 @@ XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression:
- - - - -## Supported Output Formats - -For broad compatibility with third-party tools, this library supports many -output formats. The specific file type is controlled with `bookType` option: - -| `bookType` | extension | sheets | Description | -|:-----------|:-----------|:-------|:--------------------------------| -| `xlsx` | `.xlsx` | multi | Excel 2007+ XML Format | -| `xlsm` | `.xlsm` | multi | Excel 2007+ Macro XML Format | -| `xlsb` | `.xlsb` | multi | Excel 2007+ Binary Format | -| `biff8` | `.xls` | multi | Excel 97-2004 Workbook Format | -| `biff5` | `.xls` | multi | Excel 5.0/95 Workbook Format | -| `biff4` | `.xls` | single | Excel 4.0 Worksheet Format | -| `biff3` | `.xls` | single | Excel 3.0 Worksheet Format | -| `biff2` | `.xls` | single | Excel 2.0 Worksheet Format | -| `xlml` | `.xls` | multi | Excel 2003-2004 (SpreadsheetML) | -| `numbers` | `.numbers` | multi | Numbers 3.0+ Spreadsheet | -| `ods` | `.ods` | multi | OpenDocument Spreadsheet | -| `fods` | `.fods` | multi | Flat OpenDocument Spreadsheet | -| `wk3` | `.wk3` | multi | Lotus Workbook (WK3) | -| `csv` | `.csv` | single | Comma Separated Values | -| `txt` | `.txt` | single | UTF-16 Unicode Text (TXT) | -| `sylk` | `.sylk` | single | Symbolic Link (SYLK) | -| `html` | `.html` | single | HTML Document | -| `dif` | `.dif` | single | Data Interchange Format (DIF) | -| `dbf` | `.dbf` | single | dBASE II + VFP Extensions (DBF) | -| `wk1` | `.wk1` | single | Lotus Worksheet (WK1) | -| `rtf` | `.rtf` | single | Rich Text Format (RTF) | -| `prn` | `.prn` | single | Lotus Formatted Text | -| `eth` | `.eth` | single | Ethercalc Record Format (ETH) | - -- `compression` applies to ZIP-based formats (XLSX, XLSM, XLSB, NUMBERS, ODS) -- Formats that only support a single sheet require a `sheet` option specifying - the worksheet. If the string is empty, the first worksheet is used. -- `writeFile` will automatically guess the output file format based on the file - extension if `bookType` is not specified. It will choose the first format in - the aforementioned table that matches the extension. - -## Output Type - -The `type` option specifies the JS form of the output: - -| `type` | output | -|------------|-----------------------------------------------------------------| -| `"base64"` | string: Base64 encoding of the file | -| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) | -| `"string"` | string: JS string (not compatible with binary formats) | -| `"buffer"` | nodejs Buffer | -| `"array"` | ArrayBuffer, fallback array of 8-bit unsigned int | -| `"file"` | string: path of file that will be created (nodejs only) | - -:::note pass - -For compatibility with Excel, `csv` output will always include the UTF-8 byte -order mark ("BOM"). - -The raw [`sheet_to_csv` method](/docs/api/utilities/csv#csv-output) will return -JavaScript strings without the UTF-8 BOM. - -::: diff --git a/docz/docs/index.md b/docz/docs/index.md index 0b429b6..e5a4806 100644 --- a/docz/docs/index.md +++ b/docz/docs/index.md @@ -91,7 +91,7 @@ export default App; If you are starting from scratch, create a new ViteJS + ReactJS project: ```bash -npm create vite@latest -- sheetjs-react --template react --default +npm create vite@latest -- sheetjs-react --template react --no-rolldown --no-interactive cd sheetjs-react npm install npm run dev @@ -123,19 +123,19 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} 2) Ensure that your component script imports `useRef` from the `react` library: -```js +```js title="src/App.tsx (add useRef import if it does not exist)" import { useRef } from "react"; ``` 3) Add the following line at the top of your component script: -```js +```js title="src/App.tsx (add import to the top of your component script)" import { utils, writeFileXLSX } from "xlsx"; ``` 4) Create a ref in the body of your function component: -```jsx +```jsx title="src/App.tsx (add highlighted line)" function App() { // highlight-next-line const tbl = useRef(null); @@ -144,7 +144,7 @@ function App() { 5) Attach the ref to the table element: -```jsx +```jsx title="src/App.tsx (add ref attribute to TABLE element)" function App() { // ... return ( @@ -156,7 +156,7 @@ function App() { 6) Add a button with a click handler that will export table data to XLSX: -```jsx +```jsx title="src/App.tsx (add button element to JSX)" function App() { // ... return ( @@ -172,6 +172,9 @@ function App() { {/*...*/} ``` +7) Start the development server (typically `npm run dev`) and open the app. +Click the "Export XLSX" button and open the generated file. +
diff --git a/docz/static/data/pres.numbers b/docz/static/data/pres.numbers new file mode 100644 index 0000000..610b411 Binary files /dev/null and b/docz/static/data/pres.numbers differ diff --git a/tests/bigdata/stream-nodejs.sh b/tests/bigdata/stream-nodejs.sh index 92924cd..7f3d0d1 100755 --- a/tests/bigdata/stream-nodejs.sh +++ b/tests/bigdata/stream-nodejs.sh @@ -15,7 +15,7 @@ curl -LO https://docs.sheetjs.com/stream/SheetJSNodeJStream.js curl -LO https://docs.sheetjs.com/pres.xlsx # this version uses `nvm` to cycle through node versions -for n in 0.12 4 6 8 10 12 14 16 18 20 22; do +for n in 0.12 4 6 8 10 12 14 16 18 20 22 24; do #sudo n $n nvm use $n node --version diff --git a/tests/bundler/esbuild.sh b/tests/bundler/esbuild.sh index 09e150f..3f75bcd 100755 --- a/tests/bundler/esbuild.sh +++ b/tests/bundler/esbuild.sh @@ -40,7 +40,7 @@ app.listen(7262, async() => { }); EOF -for n in 0.{9..25}; do +for n in 0.{9..27}; do npx -y esbuild@$n --version ## Browser Test diff --git a/tests/bundler/parcel.sh b/tests/bundler/parcel.sh index d6c0b20..49caa2a 100755 --- a/tests/bundler/parcel.sh +++ b/tests/bundler/parcel.sh @@ -87,7 +87,8 @@ 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 2.14.4 1.12.3; do +### NOTE: there were semver issues with 1.12.4 +for n in 2.16.1 1.12.3; do npm i --save parcel@$n npx -y parcel@$n build index.html node test.js diff --git a/tests/bundler/requirejs.sh b/tests/bundler/requirejs.sh index 4849066..4341958 100755 --- a/tests/bundler/requirejs.sh +++ b/tests/bundler/requirejs.sh @@ -86,7 +86,7 @@ app.listen(7262, async() => { await new Promise((res,rej) => setTimeout(res, 1000)); await page.click("#xport"); - await new Promise((res,rej) => setTimeout(res, 1000)); + await new Promise((res,rej) => setTimeout(res, 2000)); await browser.close(); process.exit(); }); diff --git a/tests/bundler/rollup.sh b/tests/bundler/rollup.sh new file mode 100755 index 0000000..421623b --- /dev/null +++ b/tests/bundler/rollup.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/bundler/rollup + +cd /tmp +rm -rf sheetjs-rollup +mkdir sheetjs-rollup +cd sheetjs-rollup +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +cat >index.js < { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +EOF + +cat >index.html < + + + +

SheetJS Presidents Demo

+ + + + +EOF + +npm i --save puppeteer express@4 + +cat >test.js < { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +EOF + +## RollupJS 4.x + +npm i --save rollup@4.x @rollup/plugin-node-resolve +npx -y rollup@4.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f bundle.js Presidents.xlsx + +## RollupJS 3.x + +npm i --save rollup@3.x @rollup/plugin-node-resolve +npx -y rollup@3.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f bundle.js Presidents.xlsx + +## RollupJS 2.x + +npm i --save rollup@2.x @rollup/plugin-node-resolve +npx -y rollup@2.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f bundle.js Presidents.xlsx + +## RollupJS 1.x + +npm i --save rollup@1.x rollup-plugin-node-resolve +npx -y rollup@1.x index.js --plugin rollup-plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f bundle.js Presidents.xlsx + diff --git a/tests/bundler/rspack.sh b/tests/bundler/rspack.sh new file mode 100755 index 0000000..59f7301 --- /dev/null +++ b/tests/bundler/rspack.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/bundler/rspack +cd /tmp +rm -rf sheetjs-rspack + +mkdir sheetjs-rspack +cd sheetjs-rspack +npm init -y +sed -i.bak 's#"type": "commonjs"#"sheet": "js"#g' package.json + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @rspack/core @rspack/cli + +mkdir src +cat >src/index.js < { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +EOF + +npx -p @rspack/cli rspack build + +cat >index.html < + + + +

SheetJS Presidents Demo

+ + + + +EOF + +npm i --save puppeteer express + +cat >test.js < { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +EOF + +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 + diff --git a/tests/bundler/snowpack.sh b/tests/bundler/snowpack.sh new file mode 100755 index 0000000..f7cb9c0 --- /dev/null +++ b/tests/bundler/snowpack.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/bundler/ + +cd /tmp +rm -rf sheetjs-snowpack +mkdir sheetjs-snowpack +cd sheetjs-snowpack +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +cat >index.js < { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +EOF + +cat >index.html < + + + +

SheetJS Presidents Demo

+ + + + +EOF + +npx -y snowpack@3.8.8 build + +npm i --save puppeteer express@4 +cat >test.js < { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +EOF + +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 + +cd - diff --git a/tests/bundler/systemjs.sh b/tests/bundler/systemjs.sh new file mode 100755 index 0000000..f8f5999 --- /dev/null +++ b/tests/bundler/systemjs.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/bundler/systemjs + +cd /tmp +rm -rf sheetjs-systemjs +mkdir sheetjs-systemjs +cd sheetjs-systemjs +npm init -y + +## NodeJS Demo + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +curl -LO https://docs.sheetjs.com/systemjs/SheetJSystem.js + +for v in 6.x 0.21.6 0.20.19 0.19.47; do +echo "SystemJS NodeJS version $v" + +npm i --save systemjs@$v +node SheetJSystem.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f Presidents.xlsx + +done + +## Browser Demo + +curl -LO https://docs.sheetjs.com/pres.xlsx + +npm i --save puppeteer + +cat >test.js << 'EOF' +const path = require('path'); +const puppeteer = require('puppeteer'); +(async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('https://docs.sheetjs.com/systemjs/systemjs'); + const xlf = await page.$('#xlf'); + await xlf.uploadFile(path.resolve('./pres.xlsx')); + await page.evaluate(() => { + const xlf = document.querySelector('#xlf'); + const evt = new Event('change', { bubbles: true }); + xlf.dispatchEvent(evt); + }); + await new Promise((res,rej) => setTimeout(res, 1000)); + const text = await page.$eval('#out', el => el.innerText); + console.log(text); + await browser.close(); + process.exit(); +})(); +EOF + +node test.js + diff --git a/tests/bundler/vite.sh b/tests/bundler/vite.sh index 0a58c60..ed17a2b 100755 --- a/tests/bundler/vite.sh +++ b/tests/bundler/vite.sh @@ -6,8 +6,8 @@ rm -rf sheetjs-vite-tests mkdir sheetjs-vite-tests cd sheetjs-vite-tests -for n in {3..6}; do -npm create -y vite@$n sheetjs-vite$n -- --template vue-ts +for n in {3..7}; do +npm create -y vite@$n sheetjs-vite$n -- --template vue-ts --no-rolldown --no-interactive cd sheetjs-vite$n npm i npm i --save puppeteer express@4 @@ -93,7 +93,7 @@ app.listen(7262, async() => { page.on('request', req => console.log(req.url())); await page.goto('http://localhost:7262/'); await page.click("button"); - await new Promise((res,rej) => setTimeout(res, 1000)); + await new Promise((res,rej) => setTimeout(res, 2000)); await browser.close(); process.exit(); }); diff --git a/tests/bundler/webpack.sh b/tests/bundler/webpack.sh new file mode 100755 index 0000000..b6d4e51 --- /dev/null +++ b/tests/bundler/webpack.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/bundler/webpack + +cd /tmp +rm -rf sheetjs-webpack +mkdir sheetjs-webpack +cd sheetjs-webpack +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +cat >index.js <webpack.config.js <index.html < + + + +

SheetJS Presidents Demo

+ + + + +EOF + +npm i --save puppeteer express@4 + +cat >test.js < { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +EOF + +## Webpack 2.x + +npx -y webpack@2.x -p +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f index.min.js Presidents.xlsx + +## Webpack 3.x + +npx -y webpack@3.x -p +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f index.min.js Presidents.xlsx + +## Webpack 4.x and 5.x do not need to import the standalone build + +sed -i.bak 's#/dist/xlsx.full.min.js##g' index.js + +## Webpack 4.x + +npm i --save webpack@4.x webpack-cli@4.x +npx -y webpack --mode=production +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f index.min.js Presidents.xlsx + +## Webpack 5.x + +sed -i.bak 's#"type": "commonjs"#"sheet": "js"#g' package.json +npm i --save webpack@5.x webpack-cli@5.x +npx -y webpack --mode=production +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 +rm -f index.min.js Presidents.xlsx diff --git a/tests/bundler/wmr.sh b/tests/bundler/wmr.sh new file mode 100755 index 0000000..7a40854 --- /dev/null +++ b/tests/bundler/wmr.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/bundler/ + +cd /tmp +rm -rf sheetjs-wmr +mkdir sheetjs-wmr +cd sheetjs-wmr +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +cat >index.js < { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +EOF + +cat >index.html < + + + +

SheetJS Presidents Demo

+ + + + +EOF + +npx -y wmr@3.8.0 build + +npm i --save puppeteer express@4 +cat >test.js < { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +EOF + +node test.js +npx -y xlsx-cli Presidents.xlsx | head -n 3 + +cd - diff --git a/tests/frontend/svelte.sh b/tests/frontend/svelte.sh new file mode 100755 index 0000000..64f0b79 --- /dev/null +++ b/tests/frontend/svelte.sh @@ -0,0 +1,127 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/frontend/svelte +# NOTE: the svelte scripts explicitly attach id="xport" to the buttons +cd /tmp +rm -rf sheetjs-fe-svelte +mkdir sheetjs-fe-svelte +cd sheetjs-fe-svelte + +rm -rf sheetjs-svelte +npm create -y vite@latest sheetjs-svelte -- --template svelte-ts --no-rolldown --no-interactive +cd sheetjs-svelte +npm i +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +npm i --save puppeteer express@4 + +cat >test.cjs < { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await new Promise((res,rej) => setTimeout(res, 1000)); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +EOF + +# Array of Objects + +cat >src/App.svelte < +import { onMount } from 'svelte'; +import { read, utils, writeFileXLSX } from 'xlsx'; + +/* the component state is an array of presidents */ +let pres = []; + +/* Fetch and update the state once */ +onMount(async() => { + const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer(); + const wb = read(f); // parse the array buffer + const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet + pres = utils.sheet_to_json(ws); // generate objects and update state +}); + +/* get state data and export to XLSX */ +function exportFile() { + const ws = utils.json_to_sheet(pres); + const wb = utils.book_new(); + utils.book_append_sheet(wb, ws, "Data"); + writeFileXLSX(wb, "SheetJSSvelteAoO.xlsx"); +} + + +
+
SpreadsheetState
+ {#each pres as p} + + + {/each} +
NameIndex
{p.Name}{p.Index}
+ +
+ +EOF + +npm run build + +node test.cjs +npx -y xlsx-cli SheetJSSvelteAoO.xlsx + +# HTML + +cat >src/App.svelte < +import { onMount } from 'svelte'; +import { read, utils, writeFileXLSX } from 'xlsx'; + +let html = ""; +let tbl; + +/* Fetch and update the state once */ +onMount(async() => { + const f = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer(); + const wb = read(f); // parse the array buffer + const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet + // highlight-start + html = utils.sheet_to_html(ws); // generate HTML and update state + // highlight-end +}); + +/* get state data and export to XLSX */ +function exportFile() { + // highlight-start + const elt = tbl.getElementsByTagName("TABLE")[0]; + const wb = utils.table_to_book(elt); + // highlight-end + writeFileXLSX(wb, "SheetJSSvelteHTML.xlsx"); +} + + +
+ + +
{@html html}
+ +
+EOF + +npm run build + +node test.cjs +npx -y xlsx-cli SheetJSSvelteHTML.xlsx diff --git a/tests/math/tfjs-node.sh b/tests/math/tfjs-node.sh new file mode 100755 index 0000000..272db7b --- /dev/null +++ b/tests/math/tfjs-node.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/math/tensorflow#nodejs-demo +. ~/.bashrc ## This is apparently needed in macos + +cd /tmp +rm -rf sheetjs-tfjs-csv + +mkdir sheetjs-tfjs-csv +cd sheetjs-tfjs-csv +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @tensorflow/tfjs @tensorflow/tfjs-node + +curl -LO https://docs.sheetjs.com/tfjs/SheetJSTF.js + +# this version uses `nvm` to cycle through node versions +for n in 20 22 24; do + #sudo n $n + nvm use $n + node --version + node SheetJSTF.js +done diff --git a/tests/static/vite.sh b/tests/static/vite.sh index 83816fd..6e71344 100755 --- a/tests/static/vite.sh +++ b/tests/static/vite.sh @@ -6,8 +6,8 @@ rm -rf sheetjs-vite-static mkdir sheetjs-vite-static cd sheetjs-vite-static -for n in {2..6}; do -npm create -y vite@$n sheetjs-vite-$n -- --template vue-ts +for n in {2..7}; do +npm create -y vite@$n sheetjs-vite-$n -- --template vue-ts --no-rolldown --no-interactive cd sheetjs-vite-$n npm i npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz