5.4 KiB
title | pagination_prev | pagination_next |
---|---|---|
Java + Nashorn | demos/bigdata/index | solutions/input |
import current from '/version.js'; 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 can be parsed and evaluated in a Nashorn context.
Integration Details
Initialize Nashorn
global
must be created from a Nashorn engine:
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:
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:
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:
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:
/* 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
:::
Nashorn is available without additional dependencies
- Download Nashorn and its dependencies:
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"
- Download the standalone script, shim script, and the test file:
- xlsx.full.min.js
- shim.min.js
- pres.xlsx
{`\
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
curl -LO https://sheetjs.com/pres.xlsx`}
- Download
SheetJSNashorn.java
:
curl -LO https://docs.sheetjs.com/nashorn/SheetJSNashorn.java
- Build the sample class:
javac SheetJSNashorn.java
This program tries to parse the file specified by the first argument
- Run the command directly:
java 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
- Assemble a Java Archive:
jar -cf SheetJSNashorn.jar SheetJSNashorn.class xlsx.full.min.js shim.min.js
- Verify the Java Archive.
Create new directory and copy the archives and test file:
mkdir -p sheethorn
cp *.jar pres.xlsx sheethorn
cd sheethorn
Invoke the command in the archive:
java -cp .:SheetJSNashorn.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.jar SheetJSNashorn pres.xlsx