--- title: Java + Rhino pagination_prev: demos/bigdata/index pagination_next: solutions/input --- import current from '/version.js'; Rhino is an ES3+ engine in Java. The [Standalone scripts](/docs/getting-started/installation/standalone) can be parsed and evaluated in a Rhino context. This demo wraps workbooks and sheets into separate Java classes. The final result is a JAR. :::caution Rhino does not support Uint8Array, so certain formats like NUMBERS cannot be parsed or written from Rhino JS code! ::: ## Integration Details :::note Due to code generation errors, optimization must be turned off: ```java Context context = Context.enter(); context.setOptimizationLevel(-1); ``` ::: Binary strings can be passed back and forth. _Initialize Rhino_ Rhino does not provide a `global` variable. It can be created: ```java Context cx = Context.enter(); Scriptable scope = cx.initStandardObjects(); /* Disable optimization */ cx.setOptimizationLevel(-1); /* Initialize `global` variable */ // highlight-start String s = "var global = (function(){ return this; }).call(null);"; cx.evaluateString(scope, s, "", 1, null); // highlight-end ``` _Load SheetJS Scripts_ The main library can be loaded by reading the scripts from the Java Archive and evaluating in the Rhino context: ```java /* pull source from JAR */ String s = new Scanner( SheetJS.class.getResourceAsStream("/xlsx.full.min.js") ).useDelimiter("\\Z").next(); /* evaluate */ cx.evaluateString(scope, s, "", 1, null); ``` To confirm the library is loaded, `XLSX.version` can be inspected: ```swift /* get handle to XLSX */ Object XLSX = scope.get("XLSX", scope); if(XLSX == Scriptable.NOT_FOUND) throw new Exception("XLSX not found"); /* get the version string */ String version = ((NativeObject)XLSX).get("version", scope).toString(); System.out.println("SheetJS version " + version); ``` ### Reading Files A binary string can be generated from a `byte` array: ```java static String read_file(String file) throws IOException { /* read file -> array of bytes */ byte[] b = Files.readAllBytes(Paths.get(file)); /* construct binary string */ StringBuilder sb = new StringBuilder(); for(int i = 0; i < b.length; ++i) sb.append(Character.toString((char)(b[i] < 0 ? b[i] + 256 : b[i]))); return sb.toString(); } ``` This string can be loaded into the JS engine and processed: ```java /* options argument */ String os = "q = {'type':'binary', 'WTF':1};"; NativeObject o = (NativeObject)cx.evaluateString(scope, os, "", 2, null); /* set up function arguments */ String data = read_file(path_to_file); Object args[] = {data, o}; /* call read -> wb workbook */ NativeObject nXLSX = (NativeObject)XLSX; Function readfunc = (Function)XLSX.get("read", scope); NativeObject wb = (NativeObject)readfunc.call(cx, scope, nXLSX, args); ``` `wb` will be a reference to the JS workbook object. ## Complete Example :::note This demo was tested on 2023 February 14 using Rhino 1.7.14. ::: 0) Ensure Java is installed. Create a folder for the project, download the [JAR](https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-1.7.14.jar) and rename to `rhino.jar`: ```bash mkdir sheetjs-java cd sheetjs-java curl -L -o rhino.jar https://github.com/mozilla/rhino/releases/download/Rhino1_7_14_Release/rhino-1.7.14.jar ``` 1) Download the standalone script and the test file:
{`\
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
curl -LO https://sheetjs.com/pres.xlsx`}
2) Download [`SheetJSRhino.zip`](pathname:///rhino/SheetJSRhino.zip) and unzip ```bash curl -LO https://docs.sheetjs.com/rhino/SheetJSRhino.zip unzip SheetJSRhino.zip ``` 3) Save the following code to `SheetJSRhino.java`: ```java title="SheetJSRhino.java" /* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */ /* vim: set ts=2: */ import com.sheetjs.SheetJS; import com.sheetjs.SheetJSFile; import com.sheetjs.SheetJSSheet; public class SheetJSRhino { public static void main(String args[]) throws Exception { try { SheetJS sjs = new SheetJS(); /* open file */ SheetJSFile xl = sjs.read_file(args[0]); /* get sheetnames */ String[] sheetnames = xl.get_sheet_names(); System.err.println(sheetnames[0]); /* convert to CSV */ SheetJSSheet sheet = xl.get_sheet(0); String csv = sheet.get_csv(); System.out.println(csv); } catch(Exception e) { throw e; } finally { SheetJS.close(); } } } ``` 4) Assemble `SheetJS.jar` from the demo code: ```bash javac -cp .:rhino.jar SheetJSRhino.java jar -cf SheetJS.jar SheetJSRhino.class com/sheetjs/*.class xlsx.full.min.js ``` 5) Test the program: ```bash java -cp .:SheetJS.jar:rhino.jar SheetJSRhino pres.xlsx ``` If successful, a CSV will be printed to console.