Java + Rhino
Rhino is an ES3+ engine in Java.
The Standalone scripts 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.
Rhino does not support Uint8Array, so certain formats like NUMBERS cannot be parsed or written from Rhino JS code!
Integration Details
Due to code generation errors, optimization must be turned off:
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:
Context cx = Context.enter();
Scriptable scope = cx.initStandardObjects();
/* Disable optimization */
cx.setOptimizationLevel(-1);
/* Initialize `global` variable */
String s = "var global = (function(){ return this; }).call(null);";
cx.evaluateString(scope, s, "<cmd>", 1, null);
Load SheetJS Scripts
The main library can be loaded by reading the scripts from the Java Archive and evaluating in the Rhino context:
/* pull source from JAR */
String s = new Scanner(
SheetJS.class.getResourceAsStream("/xlsx.full.min.js")
).useDelimiter("\\Z").next();
/* evaluate */
cx.evaluateString(scope, s, "<cmd>", 1, null);
To confirm the library is loaded, XLSX.version
can be inspected:
/* 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:
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:
/* options argument */
String os = "q = {'type':'binary', 'WTF':1};";
NativeObject o = (NativeObject)cx.evaluateString(scope, os, "<cmd>", 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
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
and rename to rhino.jar
:
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-latest/package/dist/xlsx.full.min.js
curl -LO https://sheetjs.com/pres.xlsx
2) Download SheetJSRhino.zip
and unzip
curl -LO https://docs.sheetjs.com/rhino/SheetJSRhino.zip
unzip SheetJSRhino.zip
3) Save the following code to 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:
javac -cp .:rhino.jar SheetJSRhino.java
jar -cf SheetJS.jar SheetJSRhino.class com/sheetjs/*.class xlsx.full.min.js
5) Test the program:
java -cp .:SheetJS.jar:rhino.jar SheetJSRhino pres.xlsx
If successful, a CSV will be printed to console.