使用 Goja 的 Golang 表格
Goja[^1] 是 ECMAScript 5 的纯 Go 实现。
¥Goja[^1] is a pure Go implementation of ECMAScript 5.
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
此演示使用 Goja 和 SheetJS 来读取和写入电子表格。我们将探讨如何在 Goja 引擎中加载 SheetJS,与 Go 程序交换二进制数据并处理电子表格和结构化数据。
¥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.
"完整示例" 部分制作了一个命令行工具,用于读取任意工作簿并将数据写入 XLSB 工作簿。
¥The "Complete Example" section makes a command-line tool for reading arbitrary workbooks and writing data to XLSB workbooks.
集成详情
¥Integration Details
SheetJS 独立脚本 可以在 Goja 上下文中解析和评估。
¥The SheetJS Standalone scripts can be parsed and evaluated in a Goja context.
初始化 Goja
¥Initialize Goja
Goja 不提供 global
变量。它可以在一行中创建:
¥Goja does not provide a global
variable. It can be created in one line:
/* initialize */
vm := goja.New()
/* goja does not expose a standard "global" by default */
v, err := vm.RunString("var global = (function(){ return this; }).call(null);")
加载 SheetJS 脚本
¥Load SheetJS Scripts
可以通过从文件系统读取脚本并在 Goja 上下文中进行评估来加载 shim 和主库:
¥The shim and main libraries can be loaded by reading the scripts from the file system and evaluating in the Goja context:
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")
要确认库已加载,可以检查 XLSX.version
:
¥To confirm the library is loaded, XLSX.version
can be inspected:
/* get version string */
v, err := vm.RunString("XLSX.version")
fmt.Printf("SheetJS library version %s\n", v)
读取文件
¥Reading Files
文件可以读入 []byte
:
¥Files can be read into []byte
:
/* read file */
data, _ := ioutil.ReadFile("sheetjs.xlsx")
[]byte
应该从 Go 转换为 ArrayBuffer
:
¥[]byte
should be converted to an ArrayBuffer
from 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"
字符串可以从 JS 上下文传递到 Go 代码:
¥"base64"
strings can be passed from the JS context to Go code:
/* 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
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | Git 提交 | 去版本 | 日期 |
---|---|---|---|
darwin-x64 | 79f3a7e | 1.23.3 | 2024-12-17 |
darwin-arm | 5ef83b8 | 1.24.0 | 2025-02-13 |
win11-x64 | 79f3a7e | 1.23.4 | 2024-12-20 |
win11-arm | 5ef83b8 | 1.24.0 | 2025-02-23 |
linux-x64 | 79f3a7e | 1.22.0 | 2025-01-02 |
linux-arm | 5ef83b8 | 1.19.8 | 2025-02-15 |
在撰写本文时,Goja 没有正确的版本号。版本由 Git 提交哈希值标识。
¥At the time of writing, Goja did not have proper version numbers. Versions are identified by Git commit hashes.
-
创建模块并安装依赖:
¥Create a module and install dependencies:
mkdir SheetGoja
cd SheetGoja
go mod init SheetGoja
go get github.com/dop251/goja
-
下载 SheetJS Standalone 脚本、shim 脚本和测试文件。将所有三个文件移动到项目目录:
¥Download the SheetJS Standalone script, shim script and test file. Move all three files to the project directory:
curl -LO https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/shim.min.js
curl -LO https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js
curl -LO https://xlsx.nodejs.cn/pres.numbers
-
下载
SheetGoja.go
:¥Download
SheetGoja.go
:
curl -LO https://xlsx.nodejs.cn/goja/SheetGoja.go
-
构建独立的
SheetGoja
二进制文件:¥Build the standalone
SheetGoja
binary:
go build SheetGoja.go
-
运行演示:
¥Run the demo:
./SheetGoja pres.numbers
如果程序成功,CSV 内容将打印到控制台并创建文件 sheetjsw.xlsb
。该文件可以用 Excel 打开。
¥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]: 该项目没有网站。该库托管在 GitHub 上。
¥The project does not have a website. The library is hosted on GitHub.