forked from sheetjs/docs.sheetjs.com
		
	goja
This commit is contained in:
		
							parent
							
								
									909b776235
								
							
						
					
					
						commit
						c2a3326377
					
				
							
								
								
									
										136
									
								
								docz/docs/03-demos/31-engines/05_goja.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										136
									
								
								docz/docs/03-demos/31-engines/05_goja.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,136 @@ | ||||
| --- | ||||
| title: Go + Goja | ||||
| pagination_prev: demos/cli | ||||
| pagination_next: demos/clipboard | ||||
| --- | ||||
| 
 | ||||
| Goja is a pure Go implementation of ECMAScript 5. | ||||
| 
 | ||||
| The [Standalone scripts](/docs/getting-started/installation/standalone) can be | ||||
| parsed and evaluated in a Goja context. | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| _Initialize Goja_ | ||||
| 
 | ||||
| Goja does not provide a `global` variable. It can be created in one line: | ||||
| 
 | ||||
| ```go | ||||
| /* initialize */ | ||||
| vm := goja.New() | ||||
| 
 | ||||
| /* goja does not expose a standard "global" by default */ | ||||
| // highlight-next-line | ||||
| v, err := vm.RunString("var global = (function(){ return this; }).call(null);") | ||||
| ``` | ||||
| 
 | ||||
| _Load SheetJS Scripts_ | ||||
| 
 | ||||
| The shim and main libraries can be loaded by reading the scripts from the file | ||||
| system and evaluating in the Goja context: | ||||
| 
 | ||||
| ```go | ||||
| func safe_run_file(vm *goja.Runtime, file string) { | ||||
|   data, err := ioutil.ReadFile(file) | ||||
|   if err != nil { panic(err) } | ||||
|   src := string(data) | ||||
|   _, err = vm.RunString(src) | ||||
|   if err != nil { panic(err) } | ||||
| } | ||||
| 
 | ||||
| // ... | ||||
|   safe_run_file(vm, "shim.min.js") | ||||
|   safe_run_file(vm, "xlsx.full.min.js") | ||||
| ``` | ||||
| 
 | ||||
| To confirm the library is loaded, `XLSX.version` can be inspected: | ||||
| 
 | ||||
| ```go | ||||
|   /* get version string */ | ||||
|   v, err := vm.RunString("XLSX.version") | ||||
|   fmt.Printf("SheetJS library version %s\n", v) | ||||
| ``` | ||||
| 
 | ||||
| ### Reading Files | ||||
| 
 | ||||
| Files can be read into `[]byte`: | ||||
| 
 | ||||
| ```go | ||||
| /* read file */ | ||||
| data, _ := ioutil.ReadFile("sheetjs.xlsx") | ||||
| ``` | ||||
| 
 | ||||
| `[]byte` should be converted to an `ArrayBuffer` from Go: | ||||
| 
 | ||||
| ```go | ||||
| /* load into engine */ | ||||
| vm.Set("buf", vm.ToValue(vm.NewArrayBuffer(data))) | ||||
| 
 | ||||
| /* parse */ | ||||
| wb, _ = vm.RunString("wb = XLSX.read(buf, {type:'buffer'});") | ||||
| ``` | ||||
| 
 | ||||
| ### Writing Files | ||||
| 
 | ||||
| `"base64"` strings can be passed from the JS context to Go code: | ||||
| 
 | ||||
| ```go | ||||
| /* write to Base64 string */ | ||||
| b64str, _ := vm.RunString("XLSX.write(wb, {type:'base64', bookType:'xlsx'})") | ||||
| 
 | ||||
| /* pull data back into Go and write to file */ | ||||
| buf, _ := base64.StdEncoding.DecodeString(b64str.String()) | ||||
| _ = ioutil.WriteFile("sheetjs.xlsx", buf, 0644) | ||||
| ``` | ||||
| 
 | ||||
| ## Complete Example | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was tested on 2023 February 14. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 0) Create a module and install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| mkdir SheetGoja | ||||
| cd SheetGoja | ||||
| go mod init SheetGoja | ||||
| go get github.com/dop251/goja | ||||
| ``` | ||||
| 
 | ||||
| 1) Download the standalone script, shim and 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> | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js | ||||
| curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js | ||||
| curl -LO https://sheetjs.com/pres.numbers | ||||
| ``` | ||||
| 
 | ||||
| 2) Download [`SheetGoja.go`](pathname:///goja/SheetGoja.go): | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/goja/SheetGoja.go | ||||
| ``` | ||||
| 
 | ||||
| 3) Build standalone `SheetGoja` binary: | ||||
| 
 | ||||
| ```bash | ||||
| go build SheetGoja.go | ||||
| ``` | ||||
| 
 | ||||
| 4) Run the demo: | ||||
| 
 | ||||
| ```bash | ||||
| ./SheetGoja pres.numbers | ||||
| ``` | ||||
| 
 | ||||
| If the program succeeded, the CSV contents will be printed to console and the | ||||
| file `sheetjsw.xlsb` will be created.  That file can be opened with Excel. | ||||
| @ -67,145 +67,9 @@ The demo includes examples in C and Perl. | ||||
| 
 | ||||
| ### Goja | ||||
| 
 | ||||
| Goja is a pure Go implementation of ECMAScript 5. It supports the standalone | ||||
| scripts out of the box. | ||||
| 
 | ||||
| **Reading data** | ||||
| 
 | ||||
| Files can be read into `[]byte`: | ||||
| 
 | ||||
| ```go | ||||
| /* read file */ | ||||
| data, _ := ioutil.ReadFile("sheetjs.xlsx") | ||||
| ``` | ||||
| 
 | ||||
| `[]byte` should be converted to an `ArrayBuffer` from Go: | ||||
| 
 | ||||
| ```go | ||||
| /* load into engine */ | ||||
| vm.Set("buf", vm.ToValue(vm.NewArrayBuffer(data))) | ||||
| 
 | ||||
| /* parse */ | ||||
| wb, _ = vm.RunString("wb = XLSX.read(buf, {type:'buffer'});") | ||||
| ``` | ||||
| 
 | ||||
| **Writing data** | ||||
| 
 | ||||
| `"base64"` strings can be decoded in Go: | ||||
| 
 | ||||
| ```go | ||||
| /* write to Base64 string */ | ||||
| b64str, _ := vm.RunString("XLSX.write(wb, {type:'base64', bookType:'xlsx'})") | ||||
| 
 | ||||
| /* pull data back into Go and write to file */ | ||||
| buf, _ := base64.StdEncoding.DecodeString(b64str.String()) | ||||
| _ = ioutil.WriteFile("sheetjs.xlsx", buf, 0644) | ||||
| ``` | ||||
| 
 | ||||
| <details><summary><b>Complete Example</b> (click to show)</summary> | ||||
| 
 | ||||
| 0) Install Go | ||||
| 
 | ||||
| 1) Create a `go.mod` file and install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| go mod init SheetGoja | ||||
| go get github.com/dop251/goja | ||||
| ``` | ||||
| 
 | ||||
| 2) Download the standalone script and the shim: | ||||
| 
 | ||||
| <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> | ||||
| </ul> | ||||
| 
 | ||||
| 3) Save the following code to `SheetGoja.go`: | ||||
| 
 | ||||
| ```go title="SheetGoja.go" | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
|   b64 "encoding/base64" | ||||
|   "fmt" | ||||
|   "os" | ||||
|   "io/ioutil" | ||||
|   "github.com/dop251/goja" | ||||
| ) | ||||
| 
 | ||||
| func safe_run_file(vm *goja.Runtime, file string) { | ||||
|   data, err := ioutil.ReadFile(file) | ||||
|   if err != nil { panic(err) } | ||||
|   src := string(data) | ||||
|   _, err = vm.RunString(src) | ||||
|   if err != nil { panic(err) } | ||||
| } | ||||
| 
 | ||||
| func eval_string(vm *goja.Runtime, cmd string) goja.Value { | ||||
|   v, err := vm.RunString(cmd) | ||||
|   if err != nil { panic(err) } | ||||
|   return v | ||||
| } | ||||
| 
 | ||||
| func write_type(vm *goja.Runtime, t string) { | ||||
|   b64str := eval_string(vm, "XLSX.write(wb, {type:'base64', bookType:'" + t + "'})") | ||||
|   buf, err := b64.StdEncoding.DecodeString(b64str.String()); | ||||
|   if err != nil { panic(err) } | ||||
|   err = ioutil.WriteFile("sheetjsg." + t, buf, 0644) | ||||
|   if err != nil { panic(err) } | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
|   vm := goja.New() | ||||
| 
 | ||||
|   /* initialize */ | ||||
|   eval_string(vm, "if(typeof global == 'undefined') global = (function(){ return this; }).call(null);") | ||||
| 
 | ||||
|   /* load library */ | ||||
|   safe_run_file(vm, "shim.min.js") | ||||
|   safe_run_file(vm, "xlsx.full.min.js") | ||||
| 
 | ||||
|   /* get version string */ | ||||
|   v := eval_string(vm, "XLSX.version") | ||||
|   fmt.Printf("SheetJS library version %s\n", v) | ||||
| 
 | ||||
|   /* read file */ | ||||
|   data, err := ioutil.ReadFile(os.Args[1]) | ||||
|   if err != nil { panic(err) } | ||||
|   vm.Set("buf", vm.ToValue(vm.NewArrayBuffer(data))) | ||||
|   fmt.Printf("Loaded file %s\n", os.Args[1]) | ||||
| 
 | ||||
|   /* parse workbook */ | ||||
|   eval_string(vm, "wb = XLSX.read(buf, {type:'buffer'});") | ||||
|   fmt.Printf("Parsed %s\n", os.Args[1]) | ||||
|   eval_string(vm, "ws = wb.Sheets[wb.SheetNames[0]]") | ||||
|   fmt.Printf("Grabbed %s\n", os.Args[1]) | ||||
| 
 | ||||
|   /* print CSV */ | ||||
|   csv := eval_string(vm, "XLSX.utils.sheet_to_csv(ws)") | ||||
|   fmt.Printf("%s\n", csv) | ||||
| 
 | ||||
|   /* write file */ | ||||
|   write_type(vm, "csv") | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| 4) Build `SheetGoja`: | ||||
| 
 | ||||
| ```bash | ||||
| go build SheetGoja.go | ||||
| ``` | ||||
| 
 | ||||
| For testing, download <https://sheetjs.com/pres.numbers> and run | ||||
| 
 | ||||
| ```bash | ||||
| ./SheetGoja pres.numbers | ||||
| ``` | ||||
| 
 | ||||
| This will print the contents as a CSV to screen AND write to `sheetjsg.csv` | ||||
| 
 | ||||
| </details> | ||||
| Goja is a pure Go implementation of ECMAScript 5. | ||||
| 
 | ||||
| This demo has been moved [to a dedicated page](/docs/demos/engines/goja). | ||||
| 
 | ||||
| ### Hermes | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										61
									
								
								docz/static/goja/SheetGoja.go
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										61
									
								
								docz/static/goja/SheetGoja.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| /* SheetGoja (C) SheetJS LLC -- https://sheetjs.com */ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
|   b64 "encoding/base64" | ||||
|   "fmt" | ||||
|   "os" | ||||
|   "io/ioutil" | ||||
|   "github.com/dop251/goja" | ||||
| ) | ||||
| 
 | ||||
| func safe_run_file(vm *goja.Runtime, file string) { | ||||
|   data, err := ioutil.ReadFile(file) | ||||
|   if err != nil { panic(err) } | ||||
|   _, err = vm.RunString(string(data)) | ||||
|   if err != nil { panic(err) } | ||||
| } | ||||
| 
 | ||||
| func eval_string(vm *goja.Runtime, cmd string) goja.Value { | ||||
|   v, err := vm.RunString(cmd) | ||||
|   if err != nil { panic(err) } | ||||
|   return v | ||||
| } | ||||
| 
 | ||||
| func write_type(vm *goja.Runtime, t string) { | ||||
|   b64str := eval_string(vm, "XLSX.write(wb, {type:'base64', bookType:'" + t + "'})") | ||||
|   buf, err := b64.StdEncoding.DecodeString(b64str.String()); | ||||
|   if err != nil { panic(err) } | ||||
|   err = ioutil.WriteFile("sheetjsw." + t, buf, 0644) | ||||
|   if err != nil { panic(err) } | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
|   /* initialize */ | ||||
|   vm := goja.New() | ||||
|   eval_string(vm, "var global = (function(){ return this; }).call(null);") | ||||
| 
 | ||||
|   /* load library */ | ||||
|   safe_run_file(vm, "shim.min.js") | ||||
|   safe_run_file(vm, "xlsx.full.min.js") | ||||
| 
 | ||||
|   /* get version string */ | ||||
|   v := eval_string(vm, "XLSX.version") | ||||
|   fmt.Printf("SheetJS library version %s\n", v) | ||||
| 
 | ||||
|   /* read file */ | ||||
|   data, err := ioutil.ReadFile(os.Args[1]) | ||||
|   if err != nil { panic(err) } | ||||
|   vm.Set("buf", vm.ToValue(vm.NewArrayBuffer(data))) | ||||
| 
 | ||||
|   /* parse workbook */ | ||||
|   eval_string(vm, "wb = XLSX.read(buf, {type:'buffer'});") | ||||
|   eval_string(vm, "ws = wb.Sheets[wb.SheetNames[0]]") | ||||
| 
 | ||||
|   /* print CSV */ | ||||
|   csv := eval_string(vm, "XLSX.utils.sheet_to_csv(ws)") | ||||
|   fmt.Printf("%s\n", csv) | ||||
| 
 | ||||
|   /* write file */ | ||||
|   write_type(vm, "xlsb") | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user