--- title: Java + Nashorn pagination_prev: demos/bigdata/index pagination_next: 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](/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 ::: Nashorn is available without additional dependencies 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" ``` 1) Download the standalone script, shim script, and the test file:
{`\
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`}
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: ```bash java 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 ``` 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: ```bash 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 ```