This commit is contained in:
SheetJS 2023-03-28 00:57:47 -04:00
parent 4471237699
commit 6baef4dae7
9 changed files with 260 additions and 110 deletions
docz
docs
02-getting-started/01-installation
03-demos
static/nashorn

@ -161,7 +161,7 @@ Bower is deprecated and the maintainers recommend using other tools.
::: :::
[Bower](https://bower.io/) plays nice with the CDN tarballs: The Bower package manager plays nice with the CDN tarballs:
<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
npx bower install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} npx bower install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}

@ -10,15 +10,6 @@ import current from '/version.js';
# Bun # Bun
[Bun](https://bun.sh/) is a JavaScript runtime powered by JavaScriptCore.
:::caution Bun support is considered experimental.
Great open source software grows with user tests and reports. Any issues should
be reported to the Bun project for further diagnosis.
:::
Each standalone release script is available at <https://cdn.sheetjs.com/>. Each standalone release script is available at <https://cdn.sheetjs.com/>.
<div><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs`}>https://cdn.sheetjs.com/xlsx-{current}/package/xlsx.mjs</a> is the URL for {current}</div><br/> <div><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs`}>https://cdn.sheetjs.com/xlsx-{current}/package/xlsx.mjs</a> is the URL for {current}</div><br/>
@ -31,6 +22,13 @@ import * as fs from 'fs';
XLSX.set_fs(fs); XLSX.set_fs(fs);
``` ```
:::caution Bun support is considered experimental.
Great open source software grows with user tests and reports. Any issues should
be reported to the Bun project for further diagnosis.
:::
## Encoding support ## Encoding support
If Encoding support is required, `cpexcel.full.mjs` must be manually imported. If Encoding support is required, `cpexcel.full.mjs` must be manually imported.

@ -5,7 +5,7 @@ pagination_next: demos/grid/index
sidebar_position: 1 sidebar_position: 1
--- ---
[ReactJS](https://reactjs.org/) is a JS library for building user interfaces. ReactJS is a JS library for building user interfaces.
This demo tries to cover common React data flow ideas and strategies. React This demo tries to cover common React data flow ideas and strategies. React
familiarity is assumed. familiarity is assumed.

@ -5,7 +5,7 @@ pagination_next: demos/grid/index
sidebar_position: 2 sidebar_position: 2
--- ---
[VueJS](https://vuejs.org/) is a JS library for building user interfaces. VueJS is a JS library for building user interfaces.
This demo covers common VueJS data flow ideas and strategies. Single-File This demo covers common VueJS data flow ideas and strategies. Single-File
Components (SFC) and VueJS familiarity is assumed. Components (SFC) and VueJS familiarity is assumed.

@ -8,7 +8,7 @@ sidebar_position: 3
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
[Angular](https://angular.io/) is a JS library for building user interfaces. Angular is a JS library for building user interfaces.
This demo tries to cover common Angular data flow ideas and strategies. Angular This demo tries to cover common Angular data flow ideas and strategies. Angular
and TypeScript familiarity is assumed. and TypeScript familiarity is assumed.

@ -5,7 +5,7 @@ pagination_next: demos/grid/index
sidebar_position: 4 sidebar_position: 4
--- ---
[Svelte](https://svelte.dev/) is a JS library for building user interfaces. Svelte is a JS library for building user interfaces.
This demo tries to cover common Svelte data flow ideas and strategies. Svelte This demo tries to cover common Svelte data flow ideas and strategies. Svelte
familiarity is assumed. familiarity is assumed.

@ -0,0 +1,204 @@
---
title: Java + Nashorn
pagination_prev: demos/bigdata/index
pagination_next: solutions/input
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Nashorn is a JavaScript engine for Java. It shipped with Java distributions
starting with Java 8 and was eventually removed in Java 15. The project was
spun off and a compatible standalone release is available for Java 15+.
The [Standalone scripts](/docs/getting-started/installation/standalone) can be
parsed and evaluated in a Nashorn context.
## Integration Details
_Initialize Nashorn_
`global` must be created from a Nashorn engine:
```java
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
/* initialize nashorn engine */
ScriptEngine engine = (new ScriptEngineManager()).getEngineByName("javascript");
/* create global */
engine.eval("var global = (function(){ return this; }).call(null);");
```
_Load SheetJS Scripts_
The main library can be loaded by reading the script from the file system and
evaluating in the Nashorn context:
```java
engine.eval(new Scanner(
SheetJS.class.getResourceAsStream("/xlsx.full.min.js")
).useDelimiter("\\Z").next());
```
To confirm the library is loaded, `XLSX.version` can be printed using the
Nashorn `print` built-in:
```java
engine.eval("print('SheetJS Version ' + XLSX.version);");
```
### Reading Files
Nashorn does not properly project `byte[]` into a JS array or `Int8Array`. The
recommended workaround is to copy the data in the JS context using the JS code:
```js
function b2a(b) {
var out = typeof Uint8Array == 'function' ? new Uint8Array(b.length) : new Array(b.length);
/* `b` is similar to Int8Array (values in the range -128 .. 127 ) */
for(var i = 0; i < out.length; i++) out[i] = (b[i] + 256) & 0xFF;
return out;
}
```
This function should be embedded in the Java code:
```java
/* read spreadsheet bytes */
engine.put("bytes", Files.readAllBytes(Paths.get(args[0])));
/* convert signed byte array to JS Uint8Array or unsigned byte array */
engine.eval(
"function b2a(b) {" +
"var out = typeof Uint8Array == 'function' ? new Uint8Array(b.length) : new Array(b.length);" +
"for(var i = 0; i < out.length; i++) out[i] = (b[i] + 256) & 0xFF;" +
"return out;" +
"}" +
"var u8a = b2a(bytes)"
);
/* parse workbook */
engine.eval("var wb = XLSX.read(u8a, {type: 'array'})");
```
## Complete Example
:::note
This demo was last tested on 2023 March 27 using:
- OpenJDK 19.0.1 + Nashorn 15.4 standalone
- OpenJDK 11.0.18 + Official Nashorn
:::
<Tabs groupId="java">
<TabItem value="stdlib" label="Java 8 - 14">
Nashorn is available without additional dependencies
</TabItem>
<TabItem value="standalone" label="Java 15+">
0) Download Nashorn and its dependencies:
```bash
curl -LO "https://search.maven.org/remotecontent?filepath=org/openjdk/nashorn/nashorn-core/15.4/nashorn-core-15.4.jar"
curl -LO "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm/9.5/asm-9.5.jar"
curl -LO "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar"
curl -LO "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar"
curl -LO "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar"
curl -LO "https://search.maven.org/remotecontent?filepath=org/ow2/asm/asm-util/9.5/asm-util-9.5.jar"
```
</TabItem>
</Tabs>
1) Download the standalone script, shim script, and the test file:
<ul>
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js`}>shim.min.js</a></li>
<li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li>
</ul>
```bash
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
curl -LO https://sheetjs.com/pres.xlsx
```
2) Download [`SheetJSNashorn.java`](pathname:///nashorn/SheetJSNashorn.java):
```bash
curl -LO https://docs.sheetjs.com/nashorn/SheetJSNashorn.java
```
3) Build the sample class:
```bash
javac SheetJSNashorn.java
```
This program tries to parse the file specified by the first argument
4) Run the command directly:
<Tabs groupId="java">
<TabItem value="stdlib" label="Java 8 - 14">
```bash
java SheetJSNashorn pres.xlsx
```
</TabItem>
<TabItem value="standalone" label="Java 15+">
```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
```
</TabItem>
</Tabs>
5) Assemble a Java Archive:
```bash
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
```
6) Verify the Java Archive.
Create new directory and copy the archives and test file:
```bash
mkdir -p sheethorn
cp *.jar pres.xlsx sheethorn
cd sheethorn
```
Invoke the command in the archive:
<Tabs groupId="java">
<TabItem value="stdlib" label="Java 8 - 14">
```bash
java -cp .:SheetJSNashorn.jar SheetJSNashorn pres.xlsx
```
</TabItem>
<TabItem value="standalone" label="Java 15+">
```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
```
</TabItem>
</Tabs>

@ -240,6 +240,13 @@ build/bin/jerry xlsx.jerry.js; echo $?
</details> </details>
### Nashorn
Nashorn shipped with some versions of Java. It is now a standalone library.
This demo has been moved [to a dedicated page](/docs/demos/engines/nashorn).
### QuickJS ### QuickJS
QuickJS is an embeddable JS engine written in C. It provides a separate set of QuickJS is an embeddable JS engine written in C. It provides a separate set of
@ -255,15 +262,6 @@ Rhino is an ES3+ engine in Java.
This demo has been moved [to a dedicated page](/docs/demos/engines/rhino). This demo has been moved [to a dedicated page](/docs/demos/engines/rhino).
## Legacy Engines
:::warning
These examples were written when the engines were maintained. New projects
should not use these engines. The demos are included for legacy deployments.
:::
### ChakraCore ### ChakraCore
:::caution :::caution
@ -342,90 +340,3 @@ ready, it will read the bundled test data and print the contents as CSV.
``` ```
</details> </details>
### Nashorn
:::caution
Nashorn shipped with Java 8. It was deprecated in Java 11 and was officially
removed in JDK 15. New Java applications should use [Rhino](#rhino).
:::
Nashorn ships with Java. It includes a command-line tool `jjs` for running JS
scripts. It is somewhat limited but does offer access to the full Java runtime.
The `load` function in `jjs` can load the minified source directly:
```js
var global = (function(){ return this; }).call(null);
load('shim.min.js');
load('xlsx.full.min.js');
```
The Java `nio` API provides the `Files.readAllBytes` method to read a file into
a byte array. To use in `XLSX.read`, the demo copies the bytes into a plain JS
array and calls `XLSX.read` with type `"array"`.
<details><summary><b>Complete Example</b> (click to show)</summary>
0) Ensure `jjs` is available on system path
1) Download the standalone script, the shim and the test file:
<ul>
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js`}>shim.min.js</a></li>
<li><a href="https://sheetjs.com/pres.numbers">pres.numbers</a></li>
</ul>
2) Save the following script to `SheetJSNashorn.js`:
```js title="SheetJSNashorn.js"
/* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */
/* load module */
var global = (function(){ return this; }).call(null);
load('shim.min.js');
load('xlsx.full.min.js');
/* helper to convert byte array to plain JS array */
function b2a(b) {
var out = new Array(b.length);
for(var i = 0; i < out.length; i++) out[i] = (b[i] < 0 ? b[i] + 256 : b[i]);
return out;
}
function process_file(path) {
java.lang.System.out.println(path);
/* read file */
var path = java.nio.file.Paths.get(path);
var bytes = java.nio.file.Files.readAllBytes(path);
var u8a = b2a(bytes);
/* read data */
var wb = XLSX.read(u8a);
/* get first worksheet as an array of arrays */
var ws = wb.Sheets[wb.SheetNames[0]];
var js = XLSX.utils.sheet_to_json(ws, {header:1});
/* print out every line */
js.forEach(function(l) { java.lang.System.out.println(JSON.stringify(l)); });
}
process_file('pres.numbers');
```
3) Test the script:
```bash
jjs SheetJSNashorn.js
```
It will print out the first worksheet contents.
</details>

@ -0,0 +1,37 @@
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
public class SheetJSNashorn {
public static void main(String[] args) throws Exception {
/* initialize */
ScriptEngine engine = (new ScriptEngineManager()).getEngineByName("javascript");
/* read script file */
engine.eval("var global = (function(){ return this; }).call(null);");
engine.eval(new Scanner(SheetJSNashorn.class.getResourceAsStream("/shim.min.js")).useDelimiter("\\Z").next());
engine.eval(new Scanner(SheetJSNashorn.class.getResourceAsStream("/xlsx.full.min.js")).useDelimiter("\\Z").next());
engine.eval("print('SheetJS Version ' + XLSX.version);");
/* read spreadsheet bytes */
engine.put("bytes", Files.readAllBytes(Paths.get(args[0])));
/* convert signed byte array to JS Uint8Array or unsigned byte array */
engine.eval("function b2a(b) {" +
"var out = typeof Uint8Array == 'function' ? new Uint8Array(b.length) : new Array(b.length);" +
"for(var i = 0; i < out.length; i++) out[i] = (b[i] + 256) & 0xFF;" +
"return out;" +
"}" +
"var u8a = b2a(bytes)");
/* parse workbook */
engine.eval("var wb = XLSX.read(u8a, {type: 'array'})");
/* get first worksheet as CSV */
engine.eval("var ws = wb.Sheets[wb.SheetNames[0]];");
Object res = engine.eval("XLSX.utils.sheet_to_csv(ws)");
System.out.println(res);
}
}