From 1a80a55e764a0fe1f8457c28141aef6623c3c661 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Wed, 29 May 2024 01:10:39 -0400 Subject: [PATCH] Command-Line testing grid --- docz/data/cli.js | 14 + docz/data/cli.xls | 124 +++++ docz/docs/03-demos/20-cli/03-nexe.md | 187 +++++++ docz/docs/03-demos/20-cli/05-pkg.md | 169 +++++++ docz/docs/03-demos/20-cli/08-boxednode.md | 214 ++++++++ .../20-cli/{09-nodesea.md => 11-nodesea.md} | 4 +- docz/docs/03-demos/20-cli/12-bunsea.md | 131 +++++ .../20-cli/{23-deno.md => 13-denosea.md} | 8 +- docz/docs/03-demos/20-cli/index.md | 461 +----------------- docz/docs/03-demos/42-engines/01-duktape.md | 4 +- docz/docs/03-demos/42-engines/02-v8.md | 140 +++++- docz/static/cli/sheet2csv.rs | 38 +- docz/static/cli/snapshot.rs | 50 +- docz/static/v8/main.rs | 9 +- tests/cli-boxednode.sh | 18 + tests/cli-bunsea.sh | 35 ++ tests/cli-denosea.sh | 16 + tests/cli-nexe.sh | 18 + tests/cli-nodesea.sh | 65 +++ tests/cli-pkg.sh | 20 + 20 files changed, 1239 insertions(+), 486 deletions(-) create mode 100644 docz/data/cli.js create mode 100644 docz/data/cli.xls create mode 100644 docz/docs/03-demos/20-cli/03-nexe.md create mode 100644 docz/docs/03-demos/20-cli/05-pkg.md create mode 100644 docz/docs/03-demos/20-cli/08-boxednode.md rename docz/docs/03-demos/20-cli/{09-nodesea.md => 11-nodesea.md} (99%) create mode 100644 docz/docs/03-demos/20-cli/12-bunsea.md rename docz/docs/03-demos/20-cli/{23-deno.md => 13-denosea.md} (97%) create mode 100755 tests/cli-boxednode.sh create mode 100755 tests/cli-bunsea.sh create mode 100755 tests/cli-denosea.sh create mode 100755 tests/cli-nexe.sh create mode 100755 tests/cli-nodesea.sh create mode 100755 tests/cli-pkg.sh diff --git a/docz/data/cli.js b/docz/data/cli.js new file mode 100644 index 0000000..21620e8 --- /dev/null +++ b/docz/data/cli.js @@ -0,0 +1,14 @@ +import { read, utils } from 'xlsx'; +import url from './cli.xls'; +import React, { useEffect, useState } from 'react'; + +const FrameworkData = () => { + const [fw, setFW] = useState(""); + + useEffect(() => { (async() => { + const wb = read(await (await fetch(url)).arrayBuffer(), { dense: true }); + setFW(utils.sheet_to_html(wb.Sheets["Frameworks"])); + })(); }, []); + return (
); +}; +export default FrameworkData; diff --git a/docz/data/cli.xls b/docz/data/cli.xls new file mode 100644 index 0000000..bcc547f --- /dev/null +++ b/docz/data/cli.xls @@ -0,0 +1,124 @@ + + + + + 10620 + 11020 + 2260 + 19600 + 1 + False + False + + + + + + + + + + + + + + + + + + + MacOS + Windows + Linux + + + Framework + x64 + ARM + x64 + ARM + x64 + ARM + + + nexe + + + + + + + + + boxednode + + + + + + + + + pkg + + + + + + + + + NodeJS SEA + + + + + + + + + Bun SEA + + + + + + + + + Deno SEA + + + + + + + + + V8 Engine + + + + + + + +
+
+
diff --git a/docz/docs/03-demos/20-cli/03-nexe.md b/docz/docs/03-demos/20-cli/03-nexe.md new file mode 100644 index 0000000..3841ad7 --- /dev/null +++ b/docz/docs/03-demos/20-cli/03-nexe.md @@ -0,0 +1,187 @@ +--- +title: Spreadsheet Tools with Nexe +sidebar_label: nexe +pagination_prev: demos/desktop/index +pagination_next: demos/data/index +sidebar_custom_props: + summary: Prebuilt NodeJS packages +--- + +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +export const r = {style: {color:"red"}}; +export const B = {style: {fontWeight:"bold"}}; + +`nexe`[^1] is a tool for generating command-line tools that embed scripts. + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses `nexe` and SheetJS to create a standalone CLI tool for parsing +spreadsheets and converting to other formats. + +:::info pass + +The latest prebuilt package matches NodeJS version `14.15.3`. + +`nexe` can build the required packages for newer NodeJS versions. + +::: + +:::note Tested Deployments + +This demo was tested in the following deployments: + +| Architecture | Version | NodeJS | Source | Date | +|:-------------|:-------------|:----------|:----------|:-----------| +| `darwin-x64` | `4.0.0-rc.6` | `14.15.3` | Pre-built | 2024-05-28 | +| `darwin-arm` | `4.0.0-rc.6` | `18.20.3` | Compiled | 2024-05-25 | +| `win10-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-04-18 | +| `win11-arm` | `4.0.0-rc.6` | `20.10.0` | Compiled | 2024-05-28 | +| `linux-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-03-21 | +| `linux-arm` | `4.0.0-rc.6` | `18.20.3` | Compiled | 2024-05-26 | + +::: + +## Integration Details + +The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be +required from scripts. `nexe` will automatically handle packaging. + +### Script Requirements + +Scripts that exclusively use SheetJS libraries and NodeJS built-in modules can +be bundled using `nexe`. + +The demo script [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) runs in NodeJS. It +is a simple command-line tool for reading and writing spreadsheets. + +## Complete Example + +0) Download the test file https://docs.sheetjs.com/pres.numbers: + +```bash +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers +``` + +1) Download [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) + +```bash +curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js +``` + +2) Install the dependencies: + + + +{`\ +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + +{`\ +pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + +{`\ +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + + +3) Create the standalone program: + +```bash +npx nexe -t 14.15.3 xlsx-cli.js +``` + +
+ Building from source (click to hide) + +When the demo was tested on ARM targets, the Nexe pre-built packages were +missing. For unsupported NodeJS versions, packages must be built from source: + + + + +```bash +npx nexe xlsx-cli.js --build --python=$(which python3) --make="-j8" +``` + + + + +On Windows x64, the `--build` flag suffices: + +```bash +npx nexe xlsx-cli.js --build --make="-j8" +``` + +On Windows ARM, the target `windows-arm64-20.10.0` must be specified: + +```bash +npx nexe xlsx-cli.js --build --make="-j8" --target=windows-arm64-20.10.0 +``` + +**`vcbuild.bat` issues** + +The Windows ARM build may fail with a `vcbuild.bat` error: + +``` +Error: vcbuild.bat nosign release arm64 exited with code: 1 +``` + +Pass the `-v` flag for more details. In the most recent test, the error stemmed +from a Python version mismatch: + +``` +Node.js configure: found Python 2.7.18 +Please use python3.11 or python3.10 or python3.9 or python3.8 or python3.7 or python3.6 +``` + +The resolved version of Python can be found with + +```cmd +where python +``` + +In the most recent test, a Python 2 version appeared first. This was fixed by +finding the Python 3 location and prepending it to `PATH`: + +```cmd +set PATH="C:\correct\path\to\python\three";%PATH% +``` + + + + +
+ +This generates `xlsx-cli` or `xlsx-cli.exe` depending on platform. + +5) Run the generated program, passing `pres.numbers` as the argument: + + + + +```bash +./xlsx-cli pres.numbers +``` + + + + +```powershell +.\xlsx-cli.exe pres.numbers +``` + + + + + +[^1]: The project does not have a website. The [source repository](https://github.com/nexe/nexe) is publicly available. +[^2]: The NodeJS website hosts [prebuilt installers](https://nodejs.org/en/download/prebuilt-installer). \ No newline at end of file diff --git a/docz/docs/03-demos/20-cli/05-pkg.md b/docz/docs/03-demos/20-cli/05-pkg.md new file mode 100644 index 0000000..79c4d9b --- /dev/null +++ b/docz/docs/03-demos/20-cli/05-pkg.md @@ -0,0 +1,169 @@ +--- +title: Packing Sheets with pkg +sidebar_label: pkg +pagination_prev: demos/desktop/index +pagination_next: demos/data/index +sidebar_custom_props: + summary: Prebuilt NodeJS packages +--- + +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +export const r = {style: {color:"red"}}; +export const B = {style: {fontWeight:"bold"}}; + +`pkg`[^1] is a tool for generating command-line tools that embed scripts. + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses `pkg` and SheetJS to create a standalone CLI tool for parsing +spreadsheets and converting to other formats. + +:::caution pass + +With the official release of [NodeJS SEA](/docs/demos/cli/nodesea), Vercel opted +to deprecate `pkg`. It is still useful for deploying apps embedding NodeJS v18 +or earlier since those versions do not support NodeJS SEA. + +::: + +:::note Tested Deployments + +This demo was tested in the following deployments: + +| Architecture | Version | NodeJS | Date | +|:-------------|:--------|:---------|:-----------| +| `darwin-x64` | `5.8.1` | `18.5.0` | 2024-05-28 | +| `darwin-arm` | `5.8.1` | `18.5.0` | 2024-05-25 | +| `win10-x64` | `5.8.1` | `18.5.0` | 2024-04-18 | +| `win11-arm` | `5.8.1` | `18.5.0` | 2024-05-28 | +| `linux-x64` | `5.8.1` | `18.5.0` | 2024-03-21 | +| `linux-arm` | `5.8.1` | `18.5.0` | 2024-05-26 | + +::: + +## Integration Details + +The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be +required from scripts. `pkg` will automatically handle packaging. + +### Script Requirements + +Scripts that exclusively use SheetJS libraries and NodeJS built-in modules can +be bundled using `pkg`. + +The demo script [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) runs in NodeJS. It +is a simple command-line tool for reading and writing spreadsheets. + +### Limitations + +:::danger pass + +When this demo was last tested, `pkg` failed with an error referencing `node20`: + +``` +> Targets not specified. Assuming: + node20-linux-arm64, node20-macos-arm64, node20-win-arm64 +> Error! No available node version satisfies 'node20' +``` + +**`pkg` does not support NodeJS 20 or 22!** + +The local NodeJS version must be rolled back to version 18. + +If `nvm` or `nvm-windows` was used to install NodeJS: + +```bash +nvm install 18 +nvm use 18 +``` + +Otherwise, on macOS and Linux, `n` can manage the global installation: + +```bash +sudo npm i -g n +sudo n 18 +``` + +On Windows, it is recommended to use a prebuilt installer[^2] + +::: + + +## Complete Example + +0) Downgrade NodeJS to major version 18 or earlier. + +1) Download the test file https://docs.sheetjs.com/pres.numbers: + +```bash +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers +``` + +2) Download [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) + +```bash +curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js +``` + +3) Install the dependencies: + + + +{`\ +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + +{`\ +pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + +{`\ +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + + +4) Create the standalone program: + +```bash +npx pkg xlsx-cli.js +``` + +This generates `xlsx-cli-linux`, `xlsx-cli-macos`, and `xlsx-cli-win.exe` . + +5) Run the generated program, passing `pres.numbers` as the argument: + + + + +```bash +./xlsx-cli-linux pres.numbers +``` + + + + +```bash +./xlsx-cli-macos pres.numbers +``` + + + + +```powershell +.\xlsx-cli-win.exe pres.numbers +``` + + + + + +[^1]: The project does not have a website. The [source repository](https://github.com/vercel/pkg) is publicly available. +[^2]: The NodeJS website hosts [prebuilt installers](https://nodejs.org/en/download/prebuilt-installer). \ No newline at end of file diff --git a/docz/docs/03-demos/20-cli/08-boxednode.md b/docz/docs/03-demos/20-cli/08-boxednode.md new file mode 100644 index 0000000..3dd2a28 --- /dev/null +++ b/docz/docs/03-demos/20-cli/08-boxednode.md @@ -0,0 +1,214 @@ +--- +title: Sheets in a Box with boxednode +sidebar_label: boxednode +pagination_prev: demos/desktop/index +pagination_next: demos/data/index +sidebar_custom_props: + summary: NodeJS binaries with scripts, built from source +--- + +import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +export const r = {style: {color:"red"}}; +export const B = {style: {fontWeight:"bold"}}; + +`boxednode`[^1] is a tool for generating command-line tools that embed scripts. +It automates the process of building NodeJS from source. + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses `boxednode` and SheetJS to create a standalone CLI tool for +parsing spreadsheets and converting to other formats. + +:::note Tested Deployments + +This demo was tested in the following deployments: + +| Architecture | Version | NodeJS | Date | +|:-------------|:--------|:----------|:-----------| +| `darwin-x64` | `2.4.0` | `22.2.0` | 2024-05-28 | +| `darwin-arm` | `2.4.3` | `22.2.0` | 2024-05-25 | +| `win10-x64` | `2.4.2` | `16.20.2` | 2024-04-18 | +| `linux-x64` | `2.4.0` | `21.7.1` | 2024-03-21 | +| `linux-arm` | `2.4.3` | `20.13.1` | 2024-05-26 | + +::: + +## Integration Details + +The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be +required from scripts. `boxednode` will automatically handle packaging. + +### Script Requirements + +Scripts that exclusively use SheetJS libraries and NodeJS built-in modules can +be bundled using `boxednode` + +The demo script [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) runs in NodeJS. It +is a simple command-line tool for reading and writing spreadsheets. + +## Complete Example + +0) Download the test file https://docs.sheetjs.com/pres.numbers: + +```bash +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers +``` + +1) Download [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) + +```bash +curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js +``` + +2) Install the dependencies: + + + +{`\ +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + +{`\ +pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + +{`\ +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} + + + + +3) Create the standalone program: + + + + +```bash +npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli +``` + +:::caution pass + +When this demo was last tested in `linux-arm`, the build failed with an error: + +
+../deps/v8/src/base/small-vector.h:  In instantiation of ‘class v8::base::SmallVector<std::pair<const v8::internal::compiler::turboshaft::PhiOp*, const v8::internal::compiler::turboshaft::OpIndex>, 16>’:
+../deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.h:444:11:   required from here
+../deps/v8/src/base/macros.h:206:55: error: static assertion failed: T should be trivially copyable
+{"  206 |"}   static_assert(::v8::base::is_trivially_copyable<T>::value, \\
+{"      |"}                                                       ^~~~~
+
+ +This affects NodeJS `22.2.0`, but does not affect `20.13.1`. It affects the +[V8 JavaScript Engine](/docs/demos/engines/v8#build-v8). + +The `-n` flag controls the target NodeJS version. For this demo, the following +command uses NodeJS `20.13.1`: + +```bash +npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli -n 20.13.1 +``` + +::: + +
+ + +```bash +npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli.exe -n 16.20.2 +``` + +:::info pass + +The Windows 10 build requires Visual Studio with "Desktop development with C++" +workload, Python 3.11, and NASM[^2]. + +**The build command must be run in "x64 Native Tools Command Prompt"** + +::: + +:::caution pass + +When the demo was last tested, the build failed: + +``` +Not an executable Python program +Could not find Python. +``` + +By default, Windows aliases `python` to a Microsoft Store installer. If the +official installer was used, the alias should be disabled manually: + +1) Open Start menu and type "app alias". Click "Manage app execution aliases". + +2) Disable the App Installer for all items with `python` in the name. + +Using Python 3.12, the build fails with an error: + +``` +Please use python3.11 or python3.10 or python3.9 or python3.8 or python3.7 or python3.6. +``` + +In the most recent test, Python 3.11.8 was installed from the official site. + +::: + +:::caution pass + +When the demo was last tested on Windows, the build failed: + +``` +error MSB8020: The build tools for Visual Studio 2019 (Platform Toolset = 'v142') cannot be found. To build using the v142 build tools, please install Visual Studio 2019 build tools. +``` + +This error was fixed by installing the `v142` build tools through the Visual +Studio installer. + +::: + +:::caution pass + +In the most recent Windows test against NodeJS `20.8.0`, the build failed due +to an issue in the OpenSSL dependency: + +``` +...\node-v20.8.0\deps\openssl\openssl\crypto\cversion.c(75,33): error C2153: integer literals must have at least one digit [...\node-v20.8.0\deps\openssl\openssl.vcxproj] +``` + +SheetJS libraries are compatible with NodeJS versions dating back to `v0.8`. The +workaround is to select NodeJS `v16.20.2` using the `-n` flag. This version was +was chosen since NodeJS `v18` upgraded the OpenSSL dependency. + +::: + + +
+ +4) Run the generated program, passing `pres.numbers` as the argument: + + + + +```bash +./xlsx-cli pres.numbers +``` + + + + +```powershell +.\xlsx-cli.exe pres.numbers +``` + + + + +[^1]: The project does not have a website. The [source repository](https://github.com/mongodb-js/boxednode) is publicly available. +[^2]: Downloads can be found [at the main NASM project website](https://www.nasm.us/) diff --git a/docz/docs/03-demos/20-cli/09-nodesea.md b/docz/docs/03-demos/20-cli/11-nodesea.md similarity index 99% rename from docz/docs/03-demos/20-cli/09-nodesea.md rename to docz/docs/03-demos/20-cli/11-nodesea.md index 07f2300..8f156a5 100644 --- a/docz/docs/03-demos/20-cli/09-nodesea.md +++ b/docz/docs/03-demos/20-cli/11-nodesea.md @@ -158,7 +158,7 @@ This demo was tested in the following deployments: | Architecture | NodeJS | Date | |:-------------|:----------|:-----------| -| `darwin-x64` | `20.11.1` | 2024-03-17 | +| `darwin-x64` | `22.2.0` | 2024-05-28 | | `win10-x64` | `20.12.0` | 2024-03-26 | | `win11-x64` | `20.13.1` | 2024-05-22 | | `linux-x64` | `20.11.1` | 2024-03-18 | @@ -237,7 +237,7 @@ node sheet2csv.js pres.numbers The script should display CSV contents from the first sheet: -``` +```text title="Expected Output" Name,Index Bill Clinton,42 GeorgeW Bush,43 diff --git a/docz/docs/03-demos/20-cli/12-bunsea.md b/docz/docs/03-demos/20-cli/12-bunsea.md new file mode 100644 index 0000000..af049bf --- /dev/null +++ b/docz/docs/03-demos/20-cli/12-bunsea.md @@ -0,0 +1,131 @@ +--- +title: BunJS SEA +pagination_prev: demos/desktop/index +pagination_next: demos/data/index +sidebar_custom_props: + summary: BunJS Single-file Executables +--- + +import current from '/version.js'; +import CodeBlock from '@theme/CodeBlock'; + +[BunJS](https://bun.sh/docs/bundler/executables) is a JavaScript runtime with +support for compiling scripts into self-contained executables. + +[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing +data from spreadsheets. + +This demo uses the Bun compiler and SheetJS to create a standalone CLI tool for +parsing spreadsheets and generating CSV rows. + +:::info pass + +It is strongly recommended to install BunJS on systems using SheetJS libraries +in command-line tools. This workaround should only be considered if a standalone +binary is considered desirable. + +::: + +:::caution BunJS support is considered experimental. + +Great open source software grows with user tests and reports. Any issues should +be reported to the BunJS project for further diagnosis. + +::: + +## Integration Details + +The [SheetJS BunJS module](/docs/getting-started/installation/bun) can be +imported from BunJS scripts. + +`bun build --compile` generates a standalone executable that includes the BunJS +runtime, user JS code and supporting scripts and assets + +### Script Requirements + +Scripts that exclusively use SheetJS libraries and BunJS built-in modules can be +bundled using BunJS. The module should be required directly: + +{`\ +const XLSX = require("xlsx");`} + + +For example, the following script accepts one command line argument, parses the +specified file using the SheetJS `readFile` method[^1], generates CSV text from +the first worksheet using `sheet_to_csv`[^2], and prints to terminal: + +{`\ +const XLSX = require("xlsx"); +\n\ +/* process.argv[2] is the first argument to the script */ +const filename = process.argv[2]; +\n\ +/* read file */ +const wb = XLSX.readFile(filename); +\n\ +/* generate CSV of first sheet */ +const ws = wb.Sheets[wb.SheetNames[0]]; +const csv = XLSX.utils.sheet_to_csv(ws); +\n\ +/* print to terminal */ +console.log(csv);`} + + +## Complete Example + +:::note Tested Deployments + +This demo was last tested in the following deployments: + +| Architecture | BunJS | Date | +|:-------------|:---------|:-----------| +| `darwin-x64` | `1.1.10` | 2024-05-28 | + +::: + +0) Install or update BunJS.[^3] + +1) Download the test file https://docs.sheetjs.com/pres.numbers: + +```bash +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers +``` + +2) Save the [contents of the `sheet2csv.ts` code block](#script-requirements) +to `sheet2csv.ts` in the project folder. + +3) Install the SheetJS dependency: + +{`\ +bun install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} + + +4) Test the script with `bun run`: + +```bash +bun run sheet2csv.ts pres.numbers +``` + +The script should display CSV contents from the first sheet: + +```text title="Expected Output" +Name,Index +Bill Clinton,42 +GeorgeW Bush,43 +Barack Obama,44 +Donald Trump,45 +Joseph Biden,46 +``` + +5) Compile and run `sheet2csv`: + +```bash +bun build ./sheet2csv.ts --compile --outfile sheet2csv +./sheet2csv pres.numbers +``` + +The program should display the same CSV contents as the script (from step 2) + +[^1]: See [`readFile` in "Reading Files"](/docs/api/parse-options) +[^2]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output) +[^3]: See ["Installation"](https://bun.sh/docs/installation) in the BunJS documentation for instructions. \ No newline at end of file diff --git a/docz/docs/03-demos/20-cli/23-deno.md b/docz/docs/03-demos/20-cli/13-denosea.md similarity index 97% rename from docz/docs/03-demos/20-cli/23-deno.md rename to docz/docs/03-demos/20-cli/13-denosea.md index 5b6f97e..26e9123 100644 --- a/docz/docs/03-demos/20-cli/23-deno.md +++ b/docz/docs/03-demos/20-cli/13-denosea.md @@ -1,5 +1,5 @@ --- -title: Deno Compiler +title: Deno SEA pagination_prev: demos/desktop/index pagination_next: demos/data/index sidebar_custom_props: @@ -69,7 +69,7 @@ const wb = XLSX.readFile(filename); \n\ /* generate CSV of first sheet */ const ws = wb.Sheets[wb.SheetNames[0]]; -const csv = utils.sheet_to_csv(ws); +const csv = XLSX.utils.sheet_to_csv(ws); \n\ /* print to terminal */ console.log(csv);`} @@ -99,7 +99,7 @@ This demo was last tested in the following deployments: | Architecture | Deno | Date | |:-------------|:---------|:-----------| -| `darwin-x64` | `1.43.1` | 2024-05-08 | +| `darwin-x64` | `1.43.6` | 2024-05-28 | | `darwin-arm` | `1.43.6` | 2024-05-23 | | `win10-x64` | `1.41.3` | 2024-03-24 | | `win11-x64` | `1.43.6` | 2024-05-25 | @@ -125,7 +125,7 @@ deno run -r --allow-read https://docs.sheetjs.com/cli/sheet2csv.ts pres.numbers The script should display CSV contents from the first sheet: -``` +```text title="Expected Output" Name,Index Bill Clinton,42 GeorgeW Bush,43 diff --git a/docz/docs/03-demos/20-cli/index.md b/docz/docs/03-demos/20-cli/index.md index 9373557..f10a2ef 100644 --- a/docz/docs/03-demos/20-cli/index.md +++ b/docz/docs/03-demos/20-cli/index.md @@ -1,5 +1,7 @@ --- -title: Command-Line Tools +title: Sheets on the Command Line +sidebar_label: Command-Line Tools +hide_table_of_contents: true pagination_prev: demos/desktop/index pagination_next: demos/data/index --- @@ -9,6 +11,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; import {useCurrentSidebarCategory} from '@docusaurus/theme-common'; +import FrameworkData from '/data/cli.js' export const r = {style: {color:"red"}}; export const B = {style: {fontWeight:"bold"}}; @@ -45,10 +48,16 @@ Demos for common standalone CLI tools are included in separate pages: ); })} +#### Platform Support + +The following frameworks have been tested on the following platforms: + + + :::tip pass The [`xlsx-cli`](https://cdn.sheetjs.com/xlsx-cli/) NodeJS script is available -as a package on the SheetJS CDN. It is an easy-to-use command-line tool for +as a package on the SheetJS CDN. It is a straightforward command-line tool for translating files between supported spreadsheet file formats. ::: @@ -65,457 +74,33 @@ server-side scripting platform cannot be installed on the target computer. ::: -## NodeJS +#### NodeJS -There are a few popular tools for compiling NodeJS scripts to CLI programs. +This demo has been organized by framework: -The demo script presents a friendly command line interface including flags: +- [`boxednode`](/docs/demos/cli/boxednode) +- [`nexe`](/docs/demos/cli/nexe) +- [`pkg`](/docs/demos/cli/pkg) -```bash -$ ./xlsx-cli -h -Usage: xlsx-cli [options] [sheetname] +#### V8 -Options: - -V, --version output the version number - -f, --file use specified workbook - -s, --sheet print specified sheet (default first sheet) -... -``` +**[The exposition has been moved to the "V8" demo.](/docs/demos/engines/v8#snapshots)** -:::note Tested Deployments +#### BunJS -This demo was tested in the following deployments: - - - - -| Architecture | Version | NodeJS | Source | Date | -|:-------------|:-------------|:----------|:----------|:-----------| -| `darwin-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-03-15 | -| `darwin-arm` | `4.0.0-rc.6` | `18.20.3` | Compiled | 2024-05-25 | -| `win10-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-04-18 | -| `win11-arm` | `4.0.0-rc.6` | `20.10.0` | Compiled | 2024-05-28 | -| `linux-x64` | `4.0.0-rc.4` | `14.15.3` | Pre-built | 2024-03-21 | -| `linux-arm` | `4.0.0-rc.6` | `18.20.3` | Compiled | 2024-05-26 | - - - - -| Architecture | Version | NodeJS | Date | -|:-------------|:--------|:---------|:-----------| -| `darwin-x64` | `5.8.1` | `18.5.0` | 2024-03-15 | -| `darwin-arm` | `5.8.1` | `18.5.0` | 2024-05-25 | -| `win10-x64` | `5.8.1` | `18.5.0` | 2024-04-18 | -| `win11-arm` | `5.8.1` | `18.5.0` | 2024-05-28 | -| `linux-x64` | `5.8.1` | `18.5.0` | 2024-03-21 | -| `linux-arm` | `5.8.1` | `18.5.0` | 2024-05-26 | - - - - -| Architecture | Version | NodeJS | Date | -|:-------------|:--------|:----------|:-----------| -| `darwin-x64` | `2.4.0` | `21.7.1` | 2024-03-15 | -| `darwin-arm` | `2.4.3` | `22.2.0` | 2024-05-25 | -| `win10-x64` | `2.4.2` | `16.20.2` | 2024-04-18 | -| `linux-x64` | `2.4.0` | `21.7.1` | 2024-03-21 | -| `linux-arm` | `2.4.3` | `20.13.1` | 2024-05-26 | - - - - -::: - -0) Download the test file https://docs.sheetjs.com/pres.numbers: - -```bash -curl -o pres.numbers https://docs.sheetjs.com/pres.numbers -``` - -1) Download [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js) - -```bash -curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js -``` - -2) Install the dependencies: - - - -{`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} - - - -{`\ -pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} - - - -{`\ -yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epipe commander@2`} - - - - -3) Follow tooling steps: - - - - -Run `nexe` and manually specify NodeJS version 14.15.3 - -```bash -npx nexe -t 14.15.3 xlsx-cli.js -``` - -This generates `xlsx-cli` or `xlsx-cli.exe` depending on platform. - -:::caution pass - -When the demo was tested on ARM targets, the Nexe pre-built packages were -missing. The package must be built from source: - - - - -```bash -npx nexe xlsx-cli.js --build --python=$(which python3) --make="-j8" -``` - - - - -```bash -npx nexe xlsx-cli.js --build --make="-j8" -``` - - - - -::: - -:::caution pass - -On Windows ARM, the target `windows-arm64-20.10.0` must be specified: - -```bash -npx nexe xlsx-cli.js --build --make="-j8" --target=windows-arm64-20.10.0 -``` - -The Windows build may fail with a `vcbuild.bat` error: - -``` -Error: vcbuild.bat nosign release arm64 exited with code: 1 -``` - -Pass the `-v` flag for more details. In the most recent test, the error stemmed -from a Python version mismatch: - -``` -Node.js configure: found Python 2.7.18 -Please use python3.11 or python3.10 or python3.9 or python3.8 or python3.7 or python3.6 -``` - -The resolved version of Python can be found with - -```cmd -where python -``` - -In the most recent test, a Python 2 version appeared first. This was fixed by -finding the Python 3 location and prepending it to `PATH`: - -```cmd -set PATH="C:\correct\path\to\python\three";%PATH% -``` - -::: - - - - -:::danger pass - -When this demo was last tested, `pkg` failed with an error referencing `node20`: - -``` -> Targets not specified. Assuming: - node20-linux-arm64, node20-macos-arm64, node20-win-arm64 -> Error! No available node version satisfies 'node20' -``` - -**`pkg` does not support NodeJS 20!** - -The local NodeJS version must be rolled back to version 18. - -If `n` is installed: - -```bash -sudo n 18 -``` - -If `nvm` was used to install NodeJS: - -```bash -nvm install 18 -nvm use 18 -``` - -::: - -Run `pkg`: - -```bash -npx pkg xlsx-cli.js -``` - -This generates `xlsx-cli-linux`, `xlsx-cli-macos`, and `xlsx-cli-win.exe` . - - - - -Run `boxednode`: - - - - -```bash -npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli -``` - -:::caution pass - -When this demo was last tested in `linux-arm`, the build failed with an error: - -
-../deps/v8/src/base/small-vector.h:  In instantiation of ‘class v8::base::SmallVector<std::pair<const v8::internal::compiler::turboshaft::PhiOp*, const v8::internal::compiler::turboshaft::OpIndex>, 16>’:
-../deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.h:444:11:   required from here
-../deps/v8/src/base/macros.h:206:55: error: static assertion failed: T should be trivially copyable
-{"  206 |"}   static_assert(::v8::base::is_trivially_copyable<T>::value, \\
-{"      |"}                                                       ^~~~~
-
- -This affects NodeJS `22.2.0`, but does not affect `20.13.1`. It affects the -[V8 JavaScript Engine](https://docs.sheetjs.com/docs/demos/engines/v8#build-v8) -and cannot easily be patched using `boxednode`. - -The `-n` flag controls the target NodeJS version. For this demo, the following -command uses NodeJS `20.13.1`: - -```bash -npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli -n 20.13.1 -``` - -::: - -
- - -```bash -npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli.exe -n 16.20.2 -``` - -:::info pass - -The Windows 10 build requires Visual Studio with "Desktop development with C++" -workload, Python 3.11, and NASM[^1]. - -**The build command must be run in "x64 Native Tools Command Prompt"** - -::: - -:::caution pass - -When the demo was last tested, the build failed: - -``` -Not an executable Python program -Could not find Python. -``` - -By default, Windows aliases `python` to a Microsoft Store installer. If the -official installer was used, the alias should be disabled manually: - -1) Open Start menu and type "app alias". Click "Manage app execution aliases". - -2) Disable the App Installer for all items with `python` in the name. - -Using Python 3.12, the build fails with an error: - -``` -Please use python3.11 or python3.10 or python3.9 or python3.8 or python3.7 or python3.6. -``` - -In the most recent test, Python 3.11.8 was installed from the official site. - -::: - -:::caution pass - -When the demo was last tested on Windows, the build failed: - -``` -error MSB8020: The build tools for Visual Studio 2019 (Platform Toolset = 'v142') cannot be found. To build using the v142 build tools, please install Visual Studio 2019 build tools. -``` - -This error was fixed by installing the `v142` build tools through the Visual -Studio installer. - -::: - -:::caution pass - -In the most recent Windows test against NodeJS `20.8.0`, the build failed due -to an issue in the OpenSSL dependency: - -``` -...\node-v20.8.0\deps\openssl\openssl\crypto\cversion.c(75,33): error C2153: integer literals must have at least one digit [...\node-v20.8.0\deps\openssl\openssl.vcxproj] -``` - -SheetJS libraries are compatible with NodeJS versions dating back to `v0.8`. The -workaround is to select NodeJS `v16.20.2` using the `-n` flag. This version was -was chosen since NodeJS `v18` upgraded the OpenSSL dependency. - -::: - - -
- -
-
- -4) Run the generated program, passing `pres.numbers` as the argument. For -example, `nexe` generates `xlsx-cli` in macOS so the command is: - -```bash -./xlsx-cli pres.numbers -``` - -`nexe` generates `xlsx-cli.exe` in Windows, so the command is: - -```powershell -.\xlsx-cli.exe pres.numbers -``` - -## V8 - -The [V8](/docs/demos/engines/v8) demo covers standalone programs that embed the -V8 engine. This demo uses the Rust integration to generate a command line tool. - -:::note Tested Deployments - -This demo was last tested in the following deployments: - -| Architecture | V8 Version | Crate | Date | -|:-------------|:--------------|:---------|:-----------| -| `darwin-x64` | `12.3.219.9` | `0.88.0` | 2024-03-15 | -| `darwin-arm` | `12.6.228.3` | `0.92.0` | 2024-05-23 | -| `win10-x64` | `12.3.219.9` | `0.88.0` | 2024-03-24 | -| `win11-x64` | `12.6.228.3` | `0.92.0` | 2024-05-23 | -| `linux-x64` | `12.3.219.9` | `0.88.0` | 2024-03-18 | -| `linux-arm` | `12.6.228.3` | `0.92.0` | 2024-05-26 | - -::: - -0) Make a new folder for the project: - -```bash -mkdir sheetjs2csv -cd sheetjs2csv -``` - -1) Download the following scripts: - -- [`Cargo.toml`](pathname:///cli/Cargo.toml) -- [`snapshot.rs`](pathname:///cli/snapshot.rs) -- [`sheet2csv.rs`](pathname:///cli/sheet2csv.rs) - -```bash -curl -o Cargo.toml https://docs.sheetjs.com/cli/Cargo.toml -curl -o snapshot.rs https://docs.sheetjs.com/cli/snapshot.rs -curl -o sheet2csv.rs https://docs.sheetjs.com/cli/sheet2csv.rs -``` - -2) Download the SheetJS Standalone script and move to the project directory: - - - -{`\ -curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} - - -3) Build the V8 snapshot: - -```bash -cargo build --bin snapshot -cargo run --bin snapshot -``` - -:::caution pass - -With some versions of the `v8` crate, the Linux AArch64 build failed with an error: - -``` -error[E0080]: evaluation of constant value failed - - | -1715 | assert!(size_of::() == size_of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: size_of::() == size_of::()' -``` - -Versions `0.75.1` and `0.82.0` are known to work. - -::: - - -4) Build `sheet2csv` (`sheet2csv.exe` in Windows): - -```bash -cargo build --release --bin sheet2csv -``` - -5) Download the test file https://docs.sheetjs.com/pres.numbers: - -```bash -curl -o pres.numbers https://docs.sheetjs.com/pres.numbers -``` - -6) Test the application: - - - - -```bash -mv target/release/sheet2csv . -./sheet2csv pres.numbers -``` - - - - -```bash -mv target/release/sheet2csv.exe . -.\sheet2csv.exe pres.numbers -``` - - - +**[The exposition has been moved to a separate page.](/docs/demos/cli/bunsea)** #### Deno -**[The exposition has been moved to a separate page.](/docs/demos/cli/deno)** +**[The exposition has been moved to a separate page.](/docs/demos/cli/denosea)** -## Dedicated Engines +#### Dedicated Engines The following demos for JS engines produce standalone programs: +- [V8](/docs/demos/engines/v8) - [Duktape](/docs/demos/engines/duktape) - [ChakraCore](/docs/demos/engines/chakra) - [QuickJS](/docs/demos/engines/quickjs) - [Goja](/docs/demos/engines/goja) - [JavaScriptCore](/docs/demos/engines/jsc) - -[^1]: Downloads can be found [at the main NASM project website](https://www.nasm.us/) \ No newline at end of file diff --git a/docz/docs/03-demos/42-engines/01-duktape.md b/docz/docs/03-demos/42-engines/01-duktape.md index d9c01a3..f70f40f 100644 --- a/docz/docs/03-demos/42-engines/01-duktape.md +++ b/docz/docs/03-demos/42-engines/01-duktape.md @@ -19,9 +19,7 @@ data from spreadsheets. The ["Complete Example"](#complete-example) section includes a complete command-line tool for reading data from spreadsheets and exporting to Excel XLSB -workbooks. - -The ["Bindings"](#bindings) section covers bindings for other ecosystems. +workbooks. ["Bindings"](#bindings) covers bindings for other ecosystems. ## Integration Details diff --git a/docz/docs/03-demos/42-engines/02-v8.md b/docz/docs/03-demos/42-engines/02-v8.md index 5196908..f27aef5 100644 --- a/docz/docs/03-demos/42-engines/02-v8.md +++ b/docz/docs/03-demos/42-engines/02-v8.md @@ -1,7 +1,7 @@ --- title: Blazing Fast Data Processing with V8 sidebar_label: C++ + V8 -description: Process structured data in C++ or Rust programs. Seamlessly integrate spreadsheets by paring V8 and SheetJS. Modernize workflows while preserving Excel compatibility. +description: Process structured data in C++ or Rust programs. Seamlessly integrate spreadsheets by pairing V8 and SheetJS. Modernize workflows while maintaining Excel compatibility. pagination_prev: demos/bigdata/index pagination_next: solutions/input --- @@ -30,6 +30,18 @@ covers V8 engine bindings for other programming languages. The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone) can be parsed and evaluated in a V8 context. +:::note pass + +This section describes a flow where the script is parsed and evaluated every +time the program is run. + +Using V8 snapshots, SheetJS libraries can be parsed and evaluated beforehand. +This greatly improves program startup time. + +The ["Snapshots"](#snapshots) section includes a complete example. + +::: + ### Initialize V8 The official V8 `hello-world` example covers initialization and cleanup. For the @@ -890,7 +902,7 @@ Pulling data from an `ArrayBuffer` back into Rust involves an unsafe operation: ```rust /* assuming JS code returns an ArrayBuffer, copy result to a Vec */ fn eval_code_ab(scope: &mut v8::HandleScope, code: &str) -> Vec { - let source = v8::String::new(scope, &code).unwrap(); + let source = v8::String::new(scope, code).unwrap(); let script = v8::Script::compile(scope, source, None).unwrap(); let result: v8::Local = script.run(scope).unwrap().try_into().unwrap(); /* In C++, `Data` returns a pointer. Collecting data into Vec is unsafe */ @@ -907,7 +919,7 @@ This demo was last tested in the following deployments: | Architecture | V8 Crate | Date | |:-------------|:---------|:-----------| -| `darwin-x64` | `0.89.0` | 2024-04-04 | +| `darwin-x64` | `0.92.0` | 2024-05-28 | | `darwin-arm` | `0.92.0` | 2024-05-25 | | `win10-x64` | `0.89.0` | 2024-03-24 | | `linux-x64` | `0.91.0` | 2024-04-25 | @@ -957,3 +969,125 @@ cargo run pres.numbers If the program succeeded, the CSV contents will be printed to console and the file `sheetjsw.xlsb` will be created. That file can be opened with Excel. + +## Snapshots + +At a high level, V8 snapshots are raw dumps of the V8 engine state. It is much +more efficient for programs to load snapshots than to evaluate code. + +### Snapshot Demo + +There are two parts to this demo: + +A) The [`snapshot`](pathname:///cli/snapshot.rs) command creates a snapshot with +the [SheetJS standalone script](/docs/getting-started/installation/standalone) +and [supplementary NUMBERS script](/docs/api/write-options#writing-options). It +will dump the snapshot to `snapshot.bin` + +B) The [`sheet2csv`](pathname:///cli/sheet2csv.rs) tool embeds `snapshot.bin`. +The tool will parse a specified file, print CSV contents of a named worksheet, +and export the workbook to NUMBERS. + +:::note Tested Deployments + +This demo was last tested in the following deployments: + +| Architecture | V8 Version | Crate | Date | +|:-------------|:--------------|:---------|:-----------| +| `darwin-x64` | `12.6.228.3` | `0.92.0` | 2024-05-28 | +| `darwin-arm` | `12.6.228.3` | `0.92.0` | 2024-05-23 | +| `win10-x64` | `12.3.219.9` | `0.88.0` | 2024-03-24 | +| `win11-x64` | `12.6.228.3` | `0.92.0` | 2024-05-23 | +| `linux-x64` | `12.3.219.9` | `0.88.0` | 2024-03-18 | +| `linux-arm` | `12.6.228.3` | `0.92.0` | 2024-05-26 | + +::: + +0) Make a new folder for the project: + +```bash +mkdir sheetjs2csv +cd sheetjs2csv +``` + +1) Download the following scripts: + +- [`Cargo.toml`](pathname:///cli/Cargo.toml) +- [`snapshot.rs`](pathname:///cli/snapshot.rs) +- [`sheet2csv.rs`](pathname:///cli/sheet2csv.rs) + +```bash +curl -o Cargo.toml https://docs.sheetjs.com/cli/Cargo.toml +curl -o snapshot.rs https://docs.sheetjs.com/cli/snapshot.rs +curl -o sheet2csv.rs https://docs.sheetjs.com/cli/sheet2csv.rs +``` + +2) Download the SheetJS Standalone script and NUMBERS supplementary script. Move +both scripts to the project directory: + + + +{`\ +curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js +curl -o xlsx.zahl.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.zahl.js`} + + +3) Build the V8 snapshot: + +```bash +cargo build --bin snapshot +cargo run --bin snapshot +``` + +:::caution pass + +In some tests, the Linux AArch64 build failed with an error: + +``` +error[E0080]: evaluation of constant value failed + + | +1715 | assert!(size_of::() == size_of::()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: size_of::() == size_of::()' +``` + +Versions `0.75.1`, `0.82.0`, and `0.92.0` are known to work. + +::: + + +4) Build `sheet2csv` (`sheet2csv.exe` in Windows): + +```bash +cargo build --release --bin sheet2csv +``` + +5) Download the test file https://docs.sheetjs.com/pres.numbers: + +```bash +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers +``` + +6) Test the application: + + + + +```bash +mv target/release/sheet2csv . +./sheet2csv pres.numbers +``` + + + + +```bash +mv target/release/sheet2csv.exe . +.\sheet2csv.exe pres.numbers +``` + + + diff --git a/docz/static/cli/sheet2csv.rs b/docz/static/cli/sheet2csv.rs index 8ec5731..2722a69 100644 --- a/docz/static/cli/sheet2csv.rs +++ b/docz/static/cli/sheet2csv.rs @@ -1,16 +1,24 @@ /* run code, get result as a Rust String */ fn eval_code(scope: &mut v8::HandleScope, code: &str) -> std::string::String { - let source = v8::String::new(scope, &code).unwrap(); + let source = v8::String::new(scope, code).unwrap(); let script = v8::Script::compile(scope, source, None).unwrap(); let result = script.run(scope).unwrap(); return result.to_string(scope).unwrap().to_rust_string_lossy(scope); } +/* assuming JS code returns an ArrayBuffer, copy result to a Vec */ +fn eval_code_ab(scope: &mut v8::HandleScope, code: &str) -> Vec { + let source = v8::String::new(scope, code).unwrap(); + let script = v8::Script::compile(scope, source, None).unwrap(); + let result: v8::Local = script.run(scope).unwrap().try_into().unwrap(); + unsafe { return std::slice::from_raw_parts_mut(result.data().unwrap().cast::().as_ptr(), result.byte_length()).to_vec(); } +} + fn main() { /* parse arguments */ let mut iter = std::env::args(); let path: String = iter.nth(1).expect("must specify a file name"); - let sheetname: String = match iter.nth(0) { + let sheetname: String = match iter.next() { Some(v) => format!("'{}'", v), None => "wb.SheetNames[0]".to_string() }; @@ -29,14 +37,24 @@ fn main() { let context_scope = &mut v8::ContextScope::new(handle_scope, context); /* read file */ - let data: Vec = std::fs::read(path.clone()).unwrap(); - let back: v8::UniqueRef = v8::ArrayBuffer::new_backing_store_from_vec(data); - let shared = back.make_shared(); - let ab: v8::Local = v8::ArrayBuffer::with_backing_store(context_scope, &shared); - let key = v8::String::new(context_scope, "buf").unwrap(); - context.global(context_scope).set(context_scope, key.into(), ab.into()); + { + let data: Vec = std::fs::read(path.clone()).unwrap(); + let back: v8::UniqueRef = v8::ArrayBuffer::new_backing_store_from_vec(data); + let shared = back.make_shared(); + let ab: v8::Local = v8::ArrayBuffer::with_backing_store(context_scope, &shared); + let key = v8::String::new(context_scope, "buf").unwrap(); + context.global(context_scope).set(context_scope, key.into(), ab.into()); + } /* print CSV of specified sheet */ - let result = eval_code(context_scope, &mut format!("var wb = XLSX.read(buf, {{dense: true}}); XLSX.utils.sheet_to_csv(wb.Sheets[{}])", sheetname)); - println!("{}", result); + { + let result = eval_code(context_scope, &format!("var wb = XLSX.read(buf, {{dense: true}}); XLSX.utils.sheet_to_csv(wb.Sheets[{}])", sheetname)); + println!("{}", result); + } + + /* write sheetjsw.numbers */ + { + let result = eval_code_ab(context_scope, "XLSX.write(wb, {type:'array', bookType:'numbers', numbers: XLSX_ZAHL_PAYLOAD})"); + std::fs::write("sheetjsw.numbers", result).unwrap(); + } } diff --git a/docz/static/cli/snapshot.rs b/docz/static/cli/snapshot.rs index 8644c08..cc1e101 100644 --- a/docz/static/cli/snapshot.rs +++ b/docz/static/cli/snapshot.rs @@ -1,38 +1,42 @@ -/* run code, get result as a Rust String */ -fn eval_code(scope: &mut v8::HandleScope, code: &str) -> std::string::String { - let source = v8::String::new(scope, &code).unwrap(); +/*! sheetjs (C) SheetJS -- https://sheetjs.com */ +/* run code and ignore result */ +fn eval_code(scope: &mut v8::HandleScope, code: &str) { + let source = v8::String::new(scope, code).unwrap(); let script = v8::Script::compile(scope, source, None).unwrap(); - let result = script.run(scope).unwrap(); - return result.to_string(scope).unwrap().to_rust_string_lossy(scope); + let _ = script.run(scope); } - fn main() { - create_snapshot(); -} - -fn create_snapshot() { /* initialize */ let platform = v8::new_default_platform(0, false).make_shared(); v8::V8::initialize_platform(platform); v8::V8::initialize(); - let startup_data = { - let mut isolate = v8::Isolate::snapshot_creator(None); - { - let handle_scope = &mut v8::HandleScope::new(&mut isolate); - let context = v8::Context::new(handle_scope); - let context_scope = &mut v8::ContextScope::new(handle_scope, context); + /* use SnapshotCreator */ + let mut isolate = v8::Isolate::snapshot_creator(None); - /* load library */ - { - let script = std::fs::read_to_string("./xlsx.full.min.js").expect("Error reading xlsx.full.min.js"); - let _result = eval_code(context_scope, &script); - } - context_scope.set_default_context(context); + /* scope enforces the lifetime of the `&mut isolate` in `handle_scope` */ + { + /* same steps as normal flow */ + let handle_scope = &mut v8::HandleScope::new(&mut isolate); + let context = v8::Context::new(handle_scope); + let context_scope = &mut v8::ContextScope::new(handle_scope, context); + + /* instructs the snapshot creator to dump the new context */ + context_scope.set_default_context(context); + + /* load scripts */ + let scripts = vec!["./xlsx.full.min.js", "./xlsx.zahl.js"]; + for path in &scripts { + let script = std::fs::read_to_string(path).unwrap_or_else(|_| panic!("Error reading {}", path)); + eval_code(context_scope, &script); } - isolate.create_blob(v8::FunctionCodeHandling::Clear).unwrap() }; + + /* create snapshot */ + let startup_data = isolate.create_blob(v8::FunctionCodeHandling::Clear).unwrap(); + + /* write to snapshot.bin */ let blob: Vec = startup_data.to_vec(); std::fs::write("snapshot.bin", blob).unwrap(); } diff --git a/docz/static/v8/main.rs b/docz/static/v8/main.rs index bd7ac47..2681483 100644 --- a/docz/static/v8/main.rs +++ b/docz/static/v8/main.rs @@ -1,7 +1,7 @@ /*! sheetjs (C) SheetJS -- https://sheetjs.com */ /* run code, get result as a Rust String */ fn eval_code(scope: &mut v8::HandleScope, code: &str) -> std::string::String { - let source = v8::String::new(scope, &code).unwrap(); + let source = v8::String::new(scope, code).unwrap(); let script = v8::Script::compile(scope, source, None).unwrap(); let result = script.run(scope).unwrap(); return result.to_string(scope).unwrap().to_rust_string_lossy(scope); @@ -9,13 +9,17 @@ fn eval_code(scope: &mut v8::HandleScope, code: &str) -> std::string::String { /* assuming JS code returns an ArrayBuffer, copy result to a Vec */ fn eval_code_ab(scope: &mut v8::HandleScope, code: &str) -> Vec { - let source = v8::String::new(scope, &code).unwrap(); + let source = v8::String::new(scope, code).unwrap(); let script = v8::Script::compile(scope, source, None).unwrap(); let result: v8::Local = script.run(scope).unwrap().try_into().unwrap(); unsafe { return std::slice::from_raw_parts_mut(result.data().unwrap().cast::().as_ptr(), result.byte_length()).to_vec(); } } fn main() { + /* parse arguments */ + let mut iter = std::env::args(); + let path: String = iter.nth(1).expect("must specify a file name"); + /* initialize */ let platform = v8::new_default_platform(0, false).make_shared(); v8::V8::initialize_platform(platform); @@ -40,7 +44,6 @@ fn main() { /* read file */ { - let path: String = std::env::args().collect::>().into_iter().nth(1).unwrap().to_string(); let data: Vec = std::fs::read(path.clone()).unwrap(); let back: v8::UniqueRef = v8::ArrayBuffer::new_backing_store_from_vec(data); let shared = back.make_shared(); diff --git a/tests/cli-boxednode.sh b/tests/cli-boxednode.sh new file mode 100755 index 0000000..b259637 --- /dev/null +++ b/tests/cli-boxednode.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/cli/boxednode +cd /tmp +rm -rf sheetjs-boxednode +mkdir sheetjs-boxednode +cd sheetjs-boxednode + +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers + +curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz exit-on-epipe commander@2 + +## NOTE: these steps are for darwin-x64 + +npx boxednode@2.4.3 -s xlsx-cli.js -t xlsx-cli + +./xlsx-cli pres.numbers diff --git a/tests/cli-bunsea.sh b/tests/cli-bunsea.sh new file mode 100755 index 0000000..6a88862 --- /dev/null +++ b/tests/cli-bunsea.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# https://docs.sheetjs.com/docs/demos/cli/bunsea +cd /tmp +rm -rf sheetjs-bunsea +mkdir sheetjs-bunsea +cd sheetjs-bunsea + +bun --version + +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers + +cat >sheet2csv.ts <sheet2csv.js <sheet2csv.json <