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