From 9230a968c33ec6a53c30aa5721f7529ef68c573f Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 26 Mar 2024 03:33:37 -0400 Subject: [PATCH] redis -> keydb --- docz/data/engines.xls | 8 +- docz/docs/03-demos/01-math/21-pandas.md | 197 +++++++++++++++--- .../02-frontend/19-bundler/14-rollup.md | 26 ++- docz/docs/03-demos/23-data/26-redis.md | 56 +++-- docz/docs/03-demos/27-local/03-storageapi.md | 2 +- docz/docs/03-demos/30-cloud/02-netsuite.md | 2 +- docz/docs/03-demos/42-engines/03-rhino.md | 36 +++- docz/docs/03-demos/42-engines/07-nashorn.md | 55 ++++- docz/docs/03-demos/42-engines/24-graaljs.md | 32 ++- 9 files changed, 347 insertions(+), 67 deletions(-) diff --git a/docz/data/engines.xls b/docz/data/engines.xls index 03dbce0..1f952f3 100644 --- a/docz/data/engines.xls +++ b/docz/data/engines.xls @@ -86,7 +86,7 @@ Java - + @@ -116,7 +116,7 @@ Java - + @@ -186,7 +186,7 @@ Java - + @@ -267,7 +267,7 @@ Python - + diff --git a/docz/docs/03-demos/01-math/21-pandas.md b/docz/docs/03-demos/01-math/21-pandas.md index b696b61..e47e798 100644 --- a/docz/docs/03-demos/01-math/21-pandas.md +++ b/docz/docs/03-demos/01-math/21-pandas.md @@ -42,6 +42,7 @@ This demo was tested in the following deployments: |:-------------|:----------------|:-------|:-------|:-----------| | `darwin-x64` | Duktape `2.7.0` | 2.2.1 | 3.12.2 | 2024-03-15 | | `darwin-arm` | Duktape `2.7.0` | 2.0.3 | 3.11.7 | 2024-02-13 | +| `win10-x64` | Duktape `2.7.0` | 2.2.1 | 3.12.2 | 2024-03-25 | | `linux-x64` | Duktape `2.7.0` | 1.5.3 | 3.11.3 | 2024-03-21 | ::: @@ -197,12 +198,29 @@ flowchart LR This example will extract data from an Apple Numbers spreadsheet and generate a DataFrame. The DataFrame will be exported to the binary XLSB spreadsheet format. +:::note pass + +The Windows build requires Visual Studio with "Desktop development with C++". +Commands must be run in a "Native Tools Command Prompt" session. + +::: + 0) Install Pandas: +```bash +python3 -m pip install pandas +``` + +:::info pass + +On macOS and Linux, the install command may require root access: + ```bash sudo python3 -m pip install pandas ``` +::: + :::note pass When `pip` is not installed, the command will fail: @@ -246,6 +264,9 @@ sudo python3 -m pip install pandas --break-system-packages 1) Build the Duktape shared library: + + + ```bash curl -LO https://duktape.org/duktape-2.7.0.tar.xz tar -xJf duktape-2.7.0.tar.xz @@ -254,18 +275,95 @@ make -f Makefile.sharedlibrary cd .. ``` + + + +```bash +curl -LO https://duktape.org/duktape-2.7.0.tar.xz +tar -xJf duktape-2.7.0.tar.xz +cd duktape-2.7.0 +make -f Makefile.sharedlibrary +cd .. +``` + + + + +- Download and extract the source tarball. Commands must be run in WSL `bash`: + +```bash +curl -LO https://duktape.org/duktape-2.7.0.tar.xz +tar -xJf duktape-2.7.0.tar.xz +``` + +(Run `bash`, then run the aforementioned commands, then run `exit` to exit WSL) + +- Enter the source folder: + +```bash +cd duktape-2.7.0 +``` + +- Edit `src\duk_config.h` and add the highlighted lines to the end of the file: + +```c title="src\duk_config.h (add highlighted lines)" +#endif /* DUK_CONFIG_H_INCLUDED */ + +// highlight-start +#define DUK_EXTERNAL_DECL extern __declspec(dllexport) +#define DUK_EXTERNAL __declspec(dllexport) +// highlight-end +``` + +- Build the Duktape DLL: + +```cmd +cl /O2 /W3 /Isrc /LD /DDUK_SINGLE_FILE /DDUK_F_DLL_BUILD /DDUK_F_WINDOWS /DDUK_COMPILING_DUKTAPE src\\duktape.c +``` + +- Move up to the parent directory: + +```bash +cd .. +``` + + + + 2) Copy the shared library to the current folder. When the demo was last tested, the shared library file name differed by platform: -| OS | name | -|:-------|:--------------------------| -| Darwin | `libduktape.207.20700.so` | -| Linux | `libduktape.so.207.20700` | +| OS | name | +|:--------|:--------------------------| +| macOS | `libduktape.207.20700.so` | +| Linux | `libduktape.so.207.20700` | +| Windows | `duktape.dll` | + + + ```bash cp duktape-*/libduktape.* . ``` + + + +```bash +cp duktape-*/libduktape.* . +``` + + + + +```cmd +copy duktape-2.7.0\duktape.dll . +``` + + + + + 3) Download the SheetJS Standalone script and move to the project directory:
    @@ -319,6 +417,36 @@ The name of the library is `libduktape.so.207.20700`: lib = "libduktape.so.207.20700" ``` + + + +The name of the library is `duktape.dll`: + +```python title="sheetjs.py (change highlighted line)" +# highlight-next-line +lib = ".\\duktape.dll" +``` + +In addition, the following changes must be made: + +- `str_to_c` must be defined as follows: + +```python title="sheetjs.py (replace str_to_c function)" +def str_to_c(s): + b = s + if type(b) == str: b = s.encode("latin1") + return [c_char_p(b), len(b)] +``` + +- `eval_file` must `open` with mode `rb`: + +```python title="sheetjs.py (edit highlighted line)" +def eval_file(ctx, path): + # highlight-next-line + with open(path, "rb") as f: + code = f.read() +``` + @@ -385,6 +513,7 @@ This demo was tested in the following deployments: |:-------------|:----------------|:--------|:-------|:-----------| | `darwin-x64` | Duktape `2.7.0` | 0.20.15 | 3.12.2 | 2024-03-15 | | `darwin-arm` | Duktape `2.7.0` | 0.20.7 | 3.11.7 | 2024-02-13 | +| `win10-x64` | Duktape `2.7.0` | 0.20.16 | 3.12.2 | 2024-03-25 | | `linux-x64` | Duktape `2.7.0` | 0.20.16 | 3.11.3 | 2024-03-21 | ::: @@ -393,53 +522,59 @@ This demo was tested in the following deployments: 1) Edit `sheetjs.py`. -Near the top of the script, change the import from `pandas` to `polars`: +- Near the top of the script, change the import from `pandas` to `polars`: -```diff title="sheetjs.py (apply changes)" --from pandas import read_csv -+from polars import read_csv +```python title="sheetjs.py (edit highlighted line)" +from io import StringIO +# highlight-next-line +from polars import read_csv + +duk = CDLL(lib) ``` -:::note pass +- Within the `export_df_to_wb` function, change the `df.to_json` line: -The red lines starting with `-` should be removed from the file and the green -lines starting with `+` should be added to the file. Black lines show the source -context and should not be changed. - -::: - -Within the `export_df_to_wb` function, change the `df.to_json` line: - -```diff title="sheetjs.py (apply changes)" - def export_df_to_wb(ctx, df, path, sheet_name="Sheet1", book_type=None): -- json = df.to_json(orient="records") -+ json = df.write_json(row_oriented=True) +```python title="sheetjs.py (edit highlighted line)" +def export_df_to_wb(ctx, df, path, sheet_name="Sheet1", book_type=None): + # highlight-next-line + json = df.write_json(row_oriented=True) ``` 2) Edit `SheetJSPandas.py`. -In the script, change `df.info()` to `df`: +- In the `process` function, change `df.info()` to `df`: -```diff title="SheetJSPandas.py (apply changes)" - def export_df_to_wb(ctx, df, path, sheet_name="Sheet1", book_type=None): -- print(df.info()) -+ print(df) +```python title="SheetJSPandas.py (edit highlighted line)" + # Generate DataFrame from first worksheet + df = wb.get_df() + # highlight-next-line + print(df) ``` Change the export filename from `SheetJSPandas.xlsb` to `SheetJSPolars.xlsb`: -```diff - # Export DataFrame to XLSB -- sheetjs.write_df(df, "SheetJSPandas.xlsb", sheet_name="DataFrame") -+ sheetjs.write_df(df, "SheetJSPolars.xlsb", sheet_name="DataFrame") +```python title="SheetJSPandas.py (edit highlighted line)" + # Export DataFrame to XLSB + # highlight-next-line + sheetjs.write_df(df, "SheetJSPolars.xlsb", sheet_name="DataFrame") ``` 3) Install Polars: ```bash -sudo python3 -m pip install polars +python3 -m pip install polars ``` +:::info pass + +On macOS and Linux, the install command may require root access: + +```bash +sudo python3 -m pip install pandas +``` + +::: + :::caution pass On Arch Linux-based platforms including the Steam Deck, the install may fail: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md b/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md index 76fc4b5..2ee86a3 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md @@ -32,10 +32,12 @@ which covers SheetJS library usage in more detail. This demo was tested in the following environments: -| Version | Date | -|:--------|:-----------| -| `4.6.1` | 2023-12-04 | -| `4.1.4` | 2023-10-21 | +| Version | Date | +|:---------|:-----------| +| `4.13.0` | 2024-03-25 | +| `3.29.4` | 2024-03-25 | +| `2.79.1` | 2024-03-25 | +| `1.32.1` | 2024-03-25 | ::: @@ -61,6 +63,16 @@ RollupJS CLI tool npx rollup index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife ``` +:::note pass + +For RollupJS major version `1`, the plugin is `rollup-plugin-node-resolve`: + +```bash +npx rollup@1.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +``` + +::: + ## Complete Example 0) Initialize a new project: @@ -76,17 +88,17 @@ npm init -y {`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz rollup@4.6.1 @rollup/plugin-node-resolve`} +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz rollup@4.x @rollup/plugin-node-resolve`} {`\ -pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz rollup@4.6.1 @rollup/plugin-node-resolve`} +pnpm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz rollup@4.x @rollup/plugin-node-resolve`} {`\ -yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz rollup@4.6.1 @rollup/plugin-node-resolve`} +yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz rollup@4.x @rollup/plugin-node-resolve`} diff --git a/docz/docs/03-demos/23-data/26-redis.md b/docz/docs/03-demos/23-data/26-redis.md index bf71c57..cedd8e3 100644 --- a/docz/docs/03-demos/23-data/26-redis.md +++ b/docz/docs/03-demos/23-data/26-redis.md @@ -1,6 +1,6 @@ --- title: Redis Databases Wrapped in Sheets -sidebar_label: Redis +sidebar_label: Redis / KeyDB description: Store complex datasets in Redis. Seamlessly save data to spreadsheets and read data from sheets using SheetJS. Enable Excel spreadsheet experts to update content. pagination_prev: demos/cli/index pagination_next: demos/local/index @@ -9,10 +9,21 @@ sidebar_custom_props: --- import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; -[Redis](https://redis.io/) is a open source in-memory data store. It is capable -of storing sets, lists and other simple data structures. +:::warning pass + +**Redis has relicensed away from open source!** + +The original BSD-3-Clause applies to version `7.2.4`. This discussion applies to +KeyDB and other servers that support the "Redis serialization protocol" (RESP). + +::: + +[KeyDB](https://docs.keydb.dev/) is a Redis-compatible in-memory data store. It +is capable of storing sets, lists and other simple data structures. [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing data from spreadsheets. @@ -25,10 +36,11 @@ from XLSX files to a Redis database and to serialize a database to a workbook. This demo was tested in the following environments: -| Redis | Connector Module | Date | -|:--------|--------------------|:----------:| -| `6.2.9` | `redis` (`4.6.11`) | 2023-12-04 | -| `7.2.3` | `redis` (`4.6.11`) | 2023-12-04 | +| Server | Connector Module | Date | +|:--------------|:-------------------|:----------:| +| KeyDB `6.3.4` | `redis` (`4.6.13`) | 2024-03-25 | +| Redis `6.2.9` | `redis` (`4.6.11`) | 2023-12-04 | +| Redis `7.2.3` | `redis` (`4.6.11`) | 2023-12-04 | ::: @@ -227,14 +239,32 @@ this demo also requires NodeJS version 18 or later. ::: -0) Set up and start a local Redis server. +0) Set up and start a local Redis-compatible server. -:::note pass +
    Redis-compatible servers (click to show) -This demo was last tested on macOS. Redis was installed with: +This demo was last tested on macOS. + +_KeyDB_ + +KeyDB was installed with: ```bash -brew install redis +brew install keydb@6.3.4 +``` + +The following command started the server process: + +```bash +keydb-server --protected-mode no +``` + +_Redis_ + +Redis was installed with: + +```bash +brew install redis@7.2 ``` The following command started the server process: @@ -243,7 +273,7 @@ The following command started the server process: /usr/local/opt/redis/bin/redis-server /usr/local/etc/redis.conf ``` -::: +
    1) Download the following scripts: @@ -258,7 +288,7 @@ curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs 2) Install dependencies: {`\ -npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.10`} +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.13`} 3) Run the test script: diff --git a/docz/docs/03-demos/27-local/03-storageapi.md b/docz/docs/03-demos/27-local/03-storageapi.md index 0473dc4..acfdc32 100644 --- a/docz/docs/03-demos/27-local/03-storageapi.md +++ b/docz/docs/03-demos/27-local/03-storageapi.md @@ -20,7 +20,7 @@ Each browser demo was tested in the following environments: | Browser | Date | |:------------|:-----------| -| Chrome 119 | 2023-11-30 | +| Chrome 122 | 2024-03-25 | | Safari 17.3 | 2024-03-12 | ::: diff --git a/docz/docs/03-demos/30-cloud/02-netsuite.md b/docz/docs/03-demos/30-cloud/02-netsuite.md index 2681b1c..2806f9f 100644 --- a/docz/docs/03-demos/30-cloud/02-netsuite.md +++ b/docz/docs/03-demos/30-cloud/02-netsuite.md @@ -26,7 +26,7 @@ This demo was verified by NetSuite consultants in the following deployments: |:----------------|:---------------|:-----------| | ScheduledScript | 2.1 | 2024-03-21 | | Restlet | 2.1 | 2023-10-05 | -| Suitelet | 2.1 | 2024-01-26 | +| Suitelet | 2.1 | 2024-03-25 | | MapReduceScript | 2.1 | 2023-12-07 | ::: diff --git a/docz/docs/03-demos/42-engines/03-rhino.md b/docz/docs/03-demos/42-engines/03-rhino.md index 7edbee9..bd04b02 100644 --- a/docz/docs/03-demos/42-engines/03-rhino.md +++ b/docz/docs/03-demos/42-engines/03-rhino.md @@ -5,6 +5,8 @@ pagination_next: solutions/input --- import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; Rhino is an ES3+ engine in Java. @@ -28,6 +30,7 @@ This demo was tested in the following deployments: | OpenJDK | Rhino | Date | |:--------|:---------|:-----------| | 21.0.1 | `1.7.14` | 2023-12-05 | +| 17.0.10 | `1.7.14` | 2024-03-25 | | 1.8.0 | `1.7.14` | 2023-12-05 | ::: @@ -195,15 +198,42 @@ public class SheetJSRhino { 6) Assemble `SheetJS.jar` from the demo code: + + + ```bash -javac -cp .:rhino.jar SheetJSRhino.java +javac -cp ".:rhino.jar" SheetJSRhino.java jar -cf SheetJS.jar SheetJSRhino.class com/sheetjs/*.class xlsx.full.min.js ``` -7) Test the program: + + ```bash -java -cp .:SheetJS.jar:rhino.jar SheetJSRhino pres.xlsx +javac -cp ".;rhino.jar" SheetJSRhino.java +jar -cf SheetJS.jar SheetJSRhino.class com/sheetjs/*.class xlsx.full.min.js ``` + + + +7) Test the program: + + + + +```bash +java -cp ".:SheetJS.jar:rhino.jar" SheetJSRhino pres.xlsx +``` + + + + +```bash +java -cp ".;SheetJS.jar;rhino.jar" SheetJSRhino pres.xlsx +``` + + + + If successful, a CSV will be printed to console. diff --git a/docz/docs/03-demos/42-engines/07-nashorn.md b/docz/docs/03-demos/42-engines/07-nashorn.md index e35e84a..2ccd6bf 100644 --- a/docz/docs/03-demos/42-engines/07-nashorn.md +++ b/docz/docs/03-demos/42-engines/07-nashorn.md @@ -110,7 +110,7 @@ This demo was tested in the following deployments: | 20.0.2 | 15.4 standalone | 2024-03-23 | | 19.0.2 | 15.4 standalone | 2024-03-23 | | 18.0.2 | 15.4 standalone | 2024-03-23 | -| 17.0.10 | 15.4 standalone | 2024-03-23 | +| 17.0.10 | 15.4 standalone | 2024-03-25 | | 16.0.1 | 15.4 standalone | 2024-03-23 | | 15.0.10 | 15.4 standalone | 2024-03-23 | | 14.0.2 | Built-in | 2024-03-23 | @@ -191,10 +191,25 @@ java SheetJSNashorn pres.xlsx +Due to Java path inconsistencies, the command depends on the operating system: + + + + ```bash -java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar SheetJSNashorn pres.xlsx +java -cp ".:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar" SheetJSNashorn pres.xlsx ``` + + + +```bash +java -cp ".;asm-9.5.jar;asm-tree-9.5.jar;asm-commons-9.5.jar;asm-analysis-9.5.jar;asm-util-9.5.jar;nashorn-core-15.4.jar" SheetJSNashorn pres.xlsx +``` + + + + @@ -221,18 +236,48 @@ cd sheethorn +Due to Java path inconsistencies, the command depends on the operating system: + + + + ```bash -java -cp .:SheetJSNashorn.jar SheetJSNashorn pres.xlsx +java -cp ".:SheetJSNashorn.jar" SheetJSNashorn pres.xlsx ``` - + ```bash -java -cp .:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar:SheetJSNashorn.jar SheetJSNashorn pres.xlsx +java -cp ".;SheetJSNashorn.jar" SheetJSNashorn pres.xlsx ``` + + + +Due to Java path inconsistencies, the command depends on the operating system: + + + + +```bash +java -cp ".:asm-9.5.jar:asm-tree-9.5.jar:asm-commons-9.5.jar:asm-analysis-9.5.jar:asm-util-9.5.jar:nashorn-core-15.4.jar:SheetJSNashorn.jar" SheetJSNashorn pres.xlsx +``` + + + + +```bash +java -cp ".;asm-9.5.jar;asm-tree-9.5.jar;asm-commons-9.5.jar;asm-analysis-9.5.jar;asm-util-9.5.jar;nashorn-core-15.4.jar;SheetJSNashorn.jar" SheetJSNashorn pres.xlsx +``` + + + + + + + This should print the same CSV rows from Step 4. diff --git a/docz/docs/03-demos/42-engines/24-graaljs.md b/docz/docs/03-demos/42-engines/24-graaljs.md index cd76a47..7f295f6 100644 --- a/docz/docs/03-demos/42-engines/24-graaljs.md +++ b/docz/docs/03-demos/42-engines/24-graaljs.md @@ -6,6 +6,8 @@ pagination_next: solutions/input --- import current from '/version.js'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; import CodeBlock from '@theme/CodeBlock'; [GraalJS](https://www.graalvm.org/latest/reference-manual/js/) is a JS engine @@ -54,6 +56,7 @@ This demo was tested in the following deployments: |:--------|:--------|:-----------| | 22 | 24.0.0 | 2024-03-23 | | 21.0.2 | 24.0.0 | 2024-03-23 | +| 17.0.10 | 24.0.0 | 2024-03-25 | ::: @@ -106,10 +109,23 @@ CSV rows from the first worksheet. 4) Run the command directly: + + + ```bash -java -cp .:js-scriptengine-24.0.0.jar:js-language-24.0.0.jar:polyglot-24.0.0.jar:collections-24.0.0.jar:truffle-api-24.0.0.jar:nativeimage-24.0.0.jar:icu4j-24.0.0.jar:regex-24.0.0.jar -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx +java -cp ".:js-scriptengine-24.0.0.jar:js-language-24.0.0.jar:polyglot-24.0.0.jar:collections-24.0.0.jar:truffle-api-24.0.0.jar:nativeimage-24.0.0.jar:icu4j-24.0.0.jar:regex-24.0.0.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx ``` + + + +```bash +java -cp ".;js-scriptengine-24.0.0.jar;js-language-24.0.0.jar;polyglot-24.0.0.jar;collections-24.0.0.jar;truffle-api-24.0.0.jar;nativeimage-24.0.0.jar;icu4j-24.0.0.jar;regex-24.0.0.jar" -D"polyglot.js.nashorn-compat=true" SheetJSNashorn pres.xlsx +``` + + + + If successful, CSV rows from the first worksheet will be displayed. ### Java Archive Test @@ -130,10 +146,22 @@ cd sheethorn 7) Run the program using the Java Archive: + + + ```bash -java -cp .:js-scriptengine-24.0.0.jar:js-language-24.0.0.jar:polyglot-24.0.0.jar:collections-24.0.0.jar:truffle-api-24.0.0.jar:nativeimage-24.0.0.jar:icu4j-24.0.0.jar:regex-24.0.0.jar:SheetJSNashorn.jar -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx +java -cp ".:js-scriptengine-24.0.0.jar:js-language-24.0.0.jar:polyglot-24.0.0.jar:collections-24.0.0.jar:truffle-api-24.0.0.jar:nativeimage-24.0.0.jar:icu4j-24.0.0.jar:regex-24.0.0.jar:SheetJSNashorn.jar" -Dpolyglot.js.nashorn-compat=true SheetJSNashorn pres.xlsx ``` + + + +```bash +java -cp ".;js-scriptengine-24.0.0.jar;js-language-24.0.0.jar;polyglot-24.0.0.jar;collections-24.0.0.jar;truffle-api-24.0.0.jar;nativeimage-24.0.0.jar;icu4j-24.0.0.jar;regex-24.0.0.jar;SheetJSNashorn.jar" -D"polyglot.js.nashorn-compat=true" SheetJSNashorn pres.xlsx +``` + + + This should print the same CSV rows from Step 4.