| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | title: Java + Rhino | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | pagination_prev: demos/bigdata/index | 
					
						
							|  |  |  | pagination_next: solutions/input | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | import current from '/version.js'; | 
					
						
							| 
									
										
										
										
											2023-05-07 13:58:36 +00:00
										 |  |  | import CodeBlock from '@theme/CodeBlock'; | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | Rhino is an ES3+ engine in Java. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-22 06:32:55 +00:00
										 |  |  | The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone) | 
					
						
							|  |  |  | can be parsed and evaluated in a Rhino context. | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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, "<cmd>", 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, "<cmd>", 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, "<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
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 20:18:07 +00:00
										 |  |  | This demo was tested on 2023-07-26 using Rhino 1.7.14. | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 0) Ensure Java is installed.  Create a folder for the project, download the | 
					
						
							| 
									
										
										
										
											2023-05-29 02:52:54 +00:00
										 |  |  | [JAR](https://repo1.maven.org/maven2/org/mozilla/rhino/1.7.14/rhino-1.7.14.jar) | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | and rename to `rhino.jar`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | mkdir sheetjs-java | 
					
						
							|  |  |  | cd sheetjs-java | 
					
						
							| 
									
										
										
										
											2023-05-29 02:52:54 +00:00
										 |  |  | curl -L -o rhino.jar https://repo1.maven.org/maven2/org/mozilla/rhino/1.7.14/rhino-1.7.14.jar | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-22 06:32:55 +00:00
										 |  |  | 1) Download the SheetJS Standalone script and the test file. Save both files in | 
					
						
							|  |  |  | the project directory: | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | <ul> | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | <li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li> | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | <li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li> | 
					
						
							|  |  |  | </ul> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-07 13:58:36 +00:00
										 |  |  | <CodeBlock language="bash">{`\ | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js | 
					
						
							|  |  |  | curl -LO https://sheetjs.com/pres.xlsx`} | 
					
						
							| 
									
										
										
										
											2023-05-07 13:58:36 +00:00
										 |  |  | </CodeBlock> | 
					
						
							| 
									
										
										
										
											2023-02-15 01:00:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. |