docs.sheetjs.com/docz/docs/03-demos/42-engines/06-goja.md

166 lines
4.4 KiB
Markdown
Raw Normal View History

2023-02-14 06:54:02 +00:00
---
title: Sheets in Golang with Goja
sidebar_label: Go + Goja
2023-02-28 11:40:44 +00:00
pagination_prev: demos/bigdata/index
pagination_next: solutions/input
2023-02-14 06:54:02 +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
Goja[^1] is a pure Go implementation of ECMAScript 5.
2023-02-14 06:54:02 +00:00
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses Goja and SheetJS to read and write spreadsheets. We'll explore
how to load SheetJS in the Goja engine, exchange binary data with a Go program
and process spreadsheets and structured data.
The ["Complete Example"](#complete-example) section makes a command-line tool
for reading arbitrary workbooks and writing data to XLSB workbooks.
2023-02-14 06:54:02 +00:00
## Integration Details
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
can be parsed and evaluated in a Goja context.
### Initialize Goja
2023-02-14 06:54:02 +00:00
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
2023-02-14 06:54:02 +00:00
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
2023-12-02 08:39:35 +00:00
:::note Tested Deployments
2023-02-14 06:54:02 +00:00
2023-06-05 20:12:53 +00:00
This demo was tested in the following deployments:
| Architecture | Git Commit | Go version | Date |
|:-------------|:-----------|:-----------|:-----------|
| `darwin-x64` | `79f3a7e` | `1.23.3` | 2024-12-17 |
2024-05-24 08:24:50 +00:00
| `darwin-arm` | `ccbae20` | `1.22.3` | 2024-05-23 |
| `win11-x64` | `79f3a7e` | `1.23.4` | 2024-12-20 |
2024-05-26 07:50:55 +00:00
| `win11-arm` | `ccbae20` | `1.22.3` | 2024-05-25 |
2024-03-22 04:45:40 +00:00
| `linux-x64` | `e401ed4` | `1.22.1` | 2024-03-21 |
2024-05-26 07:50:55 +00:00
| `linux-arm` | `ccbae20` | `1.19.8` | 2024-05-25 |
2023-08-31 22:09:08 +00:00
At the time of writing, Goja did not have proper version numbers. Versions are
identified by Git commit hashes.
2023-02-14 06:54:02 +00:00
:::
0) Create a module and install dependencies:
```bash
mkdir SheetGoja
cd SheetGoja
go mod init SheetGoja
go get github.com/dop251/goja
```
2023-09-22 06:32:55 +00:00
1) Download the SheetJS Standalone script, shim script and test file. Move all
three files to the project directory:
2023-02-14 06:54:02 +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>
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
2024-04-26 04:16:13 +00:00
<li><a href="https://docs.sheetjs.com/pres.numbers">pres.numbers</a></li>
2023-02-14 06:54:02 +00:00
</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/shim.min.js
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
2024-04-26 04:16:13 +00:00
curl -LO https://docs.sheetjs.com/pres.numbers`}
2023-05-07 13:58:36 +00:00
</CodeBlock>
2023-02-14 06:54:02 +00:00
2) Download [`SheetGoja.go`](pathname:///goja/SheetGoja.go):
```bash
curl -LO https://docs.sheetjs.com/goja/SheetGoja.go
```
2023-09-22 06:32:55 +00:00
3) Build the standalone `SheetGoja` binary:
2023-02-14 06:54:02 +00:00
```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.
[^1]: The project does not have a website. The library is hosted on [GitHub](https://pkg.go.dev/github.com/dop251/goja).