forked from sheetjs/docs.sheetjs.com
		
	nashorn
This commit is contained in:
		
							parent
							
								
									4471237699
								
							
						
					
					
						commit
						6baef4dae7
					
				| @ -161,7 +161,7 @@ Bower is deprecated and the maintainers recommend using other tools. | ||||
| ::: | ||||
| 
 | ||||
| 
 | ||||
| [Bower](https://bower.io/) plays nice with the CDN tarballs: | ||||
| The Bower package manager plays nice with the CDN tarballs: | ||||
| 
 | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| npx bower install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
|  | ||||
| @ -10,15 +10,6 @@ import current from '/version.js'; | ||||
| 
 | ||||
| # Bun | ||||
| 
 | ||||
| [Bun](https://bun.sh/) is a JavaScript runtime powered by JavaScriptCore. | ||||
| 
 | ||||
| :::caution Bun support is considered experimental. | ||||
| 
 | ||||
| Great open source software grows with user tests and reports. Any issues should | ||||
| be reported to the Bun project for further diagnosis. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Each standalone release script is available at <https://cdn.sheetjs.com/>. | ||||
| 
 | ||||
| <div><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs`}>https://cdn.sheetjs.com/xlsx-{current}/package/xlsx.mjs</a> is the URL for {current}</div><br/> | ||||
| @ -31,6 +22,13 @@ import * as fs from 'fs'; | ||||
| XLSX.set_fs(fs); | ||||
| ``` | ||||
| 
 | ||||
| :::caution Bun support is considered experimental. | ||||
| 
 | ||||
| Great open source software grows with user tests and reports. Any issues should | ||||
| be reported to the Bun project for further diagnosis. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Encoding support | ||||
| 
 | ||||
| If Encoding support is required, `cpexcel.full.mjs` must be manually imported. | ||||
|  | ||||
| @ -5,7 +5,7 @@ pagination_next: demos/grid/index | ||||
| sidebar_position: 1 | ||||
| --- | ||||
| 
 | ||||
| [ReactJS](https://reactjs.org/) is a JS library for building user interfaces. | ||||
| ReactJS is a JS library for building user interfaces. | ||||
| 
 | ||||
| This demo tries to cover common React data flow ideas and strategies. React | ||||
| familiarity is assumed. | ||||
|  | ||||
| @ -5,7 +5,7 @@ pagination_next: demos/grid/index | ||||
| sidebar_position: 2 | ||||
| --- | ||||
| 
 | ||||
| [VueJS](https://vuejs.org/) is a JS library for building user interfaces. | ||||
| VueJS is a JS library for building user interfaces. | ||||
| 
 | ||||
| This demo covers common VueJS data flow ideas and strategies.  Single-File | ||||
| Components (SFC) and VueJS familiarity is assumed. | ||||
|  | ||||
| @ -8,7 +8,7 @@ sidebar_position: 3 | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| 
 | ||||
| [Angular](https://angular.io/) is a JS library for building user interfaces. | ||||
| Angular is a JS library for building user interfaces. | ||||
| 
 | ||||
| This demo tries to cover common Angular data flow ideas and strategies. Angular | ||||
| and TypeScript familiarity is assumed. | ||||
|  | ||||
| @ -5,7 +5,7 @@ pagination_next: demos/grid/index | ||||
| sidebar_position: 4 | ||||
| --- | ||||
| 
 | ||||
| [Svelte](https://svelte.dev/) is a JS library for building user interfaces. | ||||
| Svelte is a JS library for building user interfaces. | ||||
| 
 | ||||
| This demo tries to cover common Svelte data flow ideas and strategies. Svelte | ||||
| familiarity is assumed. | ||||
|  | ||||
							
								
								
									
										204
									
								
								docz/docs/03-demos/12-engines/04_nashorn.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										204
									
								
								docz/docs/03-demos/12-engines/04_nashorn.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,204 @@ | ||||
| --- | ||||
| title: Java + Nashorn | ||||
| pagination_prev: demos/bigdata/index | ||||
| pagination_next: solutions/input | ||||
| --- | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| <Tabs groupId="java"> | ||||
|   <TabItem value="stdlib" label="Java 8 - 14"> | ||||
| 
 | ||||
| Nashorn is available without additional dependencies | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="standalone" label="Java 15+"> | ||||
| 
 | ||||
| 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" | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 1) Download the standalone script, shim script, and the test file: | ||||
| 
 | ||||
| <ul> | ||||
| <li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li> | ||||
| <li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js`}>shim.min.js</a></li> | ||||
| <li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li> | ||||
| </ul> | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js | ||||
| curl -LO https://cdn.sheetjs.com/xlsx-latest/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: | ||||
| 
 | ||||
| <Tabs groupId="java"> | ||||
|   <TabItem value="stdlib" label="Java 8 - 14"> | ||||
| 
 | ||||
| ```bash | ||||
| java SheetJSNashorn pres.xlsx | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="standalone" label="Java 15+"> | ||||
| 
 | ||||
| ```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 | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 
 | ||||
| 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: | ||||
| 
 | ||||
| <Tabs groupId="java"> | ||||
|   <TabItem value="stdlib" label="Java 8 - 14"> | ||||
| 
 | ||||
| ```bash | ||||
| java -cp .:SheetJSNashorn.jar SheetJSNashorn pres.xlsx | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="standalone" label="Java 15+"> | ||||
| 
 | ||||
| ```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 | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| @ -240,6 +240,13 @@ build/bin/jerry xlsx.jerry.js; echo $? | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| ### Nashorn | ||||
| 
 | ||||
| Nashorn shipped with some versions of Java.  It is now a standalone library. | ||||
| 
 | ||||
| This demo has been moved [to a dedicated page](/docs/demos/engines/nashorn). | ||||
| 
 | ||||
| 
 | ||||
| ### QuickJS | ||||
| 
 | ||||
| QuickJS is an embeddable JS engine written in C.  It provides a separate set of | ||||
| @ -255,15 +262,6 @@ Rhino is an ES3+ engine in Java. | ||||
| 
 | ||||
| This demo has been moved [to a dedicated page](/docs/demos/engines/rhino). | ||||
| 
 | ||||
| ## Legacy Engines | ||||
| 
 | ||||
| :::warning | ||||
| 
 | ||||
| These examples were written when the engines were maintained. New projects | ||||
| should not use these engines. The demos are included for legacy deployments. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### ChakraCore | ||||
| 
 | ||||
| :::caution | ||||
| @ -342,90 +340,3 @@ ready, it will read the bundled test data and print the contents as CSV. | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 
 | ||||
| ### Nashorn | ||||
| 
 | ||||
| :::caution | ||||
| 
 | ||||
| Nashorn shipped with Java 8.  It was deprecated in Java 11 and was officially | ||||
| removed in JDK 15.  New Java applications should use [Rhino](#rhino). | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 
 | ||||
| Nashorn ships with Java.  It includes a command-line tool `jjs` for running JS | ||||
| scripts.  It is somewhat limited but does offer access to the full Java runtime. | ||||
| 
 | ||||
| The `load` function in `jjs` can load the minified source directly: | ||||
| 
 | ||||
| ```js | ||||
| var global = (function(){ return this; }).call(null); | ||||
| load('shim.min.js'); | ||||
| load('xlsx.full.min.js'); | ||||
| ``` | ||||
| 
 | ||||
| The Java `nio` API provides the `Files.readAllBytes` method to read a file into | ||||
| a byte array.  To use in `XLSX.read`, the demo copies the bytes into a plain JS | ||||
| array and calls `XLSX.read` with type `"array"`. | ||||
| 
 | ||||
| <details><summary><b>Complete Example</b> (click to show)</summary> | ||||
| 
 | ||||
| 0) Ensure `jjs` is available on system path | ||||
| 
 | ||||
| 1) Download the standalone script, the shim and the test file: | ||||
| 
 | ||||
| <ul> | ||||
| <li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li> | ||||
| <li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js`}>shim.min.js</a></li> | ||||
| <li><a href="https://sheetjs.com/pres.numbers">pres.numbers</a></li> | ||||
| </ul> | ||||
| 
 | ||||
| 2) Save the following script to `SheetJSNashorn.js`: | ||||
| 
 | ||||
| ```js title="SheetJSNashorn.js" | ||||
| /* sheetjs (C) 2013-present  SheetJS -- https://sheetjs.com */ | ||||
| 
 | ||||
| /* load module */ | ||||
| var global = (function(){ return this; }).call(null); | ||||
| load('shim.min.js'); | ||||
| load('xlsx.full.min.js'); | ||||
| 
 | ||||
| /* helper to convert byte array to plain JS array */ | ||||
| function b2a(b) { | ||||
|   var out = new Array(b.length); | ||||
|   for(var i = 0; i < out.length; i++) out[i] = (b[i] < 0 ? b[i] + 256 : b[i]); | ||||
|   return out; | ||||
| } | ||||
| 
 | ||||
| function process_file(path) { | ||||
|   java.lang.System.out.println(path); | ||||
| 
 | ||||
|   /* read file */ | ||||
|   var path = java.nio.file.Paths.get(path); | ||||
|   var bytes = java.nio.file.Files.readAllBytes(path); | ||||
|   var u8a = b2a(bytes); | ||||
| 
 | ||||
|   /* read data */ | ||||
|   var wb = XLSX.read(u8a); | ||||
| 
 | ||||
|   /* get first worksheet as an array of arrays */ | ||||
|   var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
|   var js = XLSX.utils.sheet_to_json(ws, {header:1}); | ||||
| 
 | ||||
|   /* print out every line */ | ||||
|   js.forEach(function(l) { java.lang.System.out.println(JSON.stringify(l)); }); | ||||
| } | ||||
| 
 | ||||
| process_file('pres.numbers'); | ||||
| ``` | ||||
| 
 | ||||
| 3) Test the script: | ||||
| 
 | ||||
| ```bash | ||||
| jjs SheetJSNashorn.js | ||||
| ``` | ||||
| 
 | ||||
| It will print out the first worksheet contents. | ||||
| 
 | ||||
| </details> | ||||
|  | ||||
							
								
								
									
										37
									
								
								docz/static/nashorn/SheetJSNashorn.java
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										37
									
								
								docz/static/nashorn/SheetJSNashorn.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| import javax.script.ScriptEngine; | ||||
| import javax.script.ScriptEngineManager; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.Scanner; | ||||
| 
 | ||||
| public class SheetJSNashorn { | ||||
|   public static void main(String[] args) throws Exception { | ||||
|     /* initialize */ | ||||
|     ScriptEngine engine = (new ScriptEngineManager()).getEngineByName("javascript"); | ||||
| 
 | ||||
|     /* read script file */ | ||||
|     engine.eval("var global = (function(){ return this; }).call(null);"); | ||||
|     engine.eval(new Scanner(SheetJSNashorn.class.getResourceAsStream("/shim.min.js")).useDelimiter("\\Z").next()); | ||||
|     engine.eval(new Scanner(SheetJSNashorn.class.getResourceAsStream("/xlsx.full.min.js")).useDelimiter("\\Z").next()); | ||||
|     engine.eval("print('SheetJS Version ' + XLSX.version);"); | ||||
| 
 | ||||
|     /* 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'})"); | ||||
| 
 | ||||
|     /* get first worksheet as CSV */ | ||||
|     engine.eval("var ws = wb.Sheets[wb.SheetNames[0]];"); | ||||
|     Object res = engine.eval("XLSX.utils.sheet_to_csv(ws)"); | ||||
|     System.out.println(res); | ||||
|   } | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user