使用 Duktape 进行数据处理
Duktape 是一个用 C 编写的嵌入式 JS 引擎。它已被移植到许多奇异的体系结构和操作系统。
¥Duktape is an embeddable JS engine written in C. It has been ported to a number of exotic architectures and operating systems.
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
"完整示例" 部分包括一个完整的命令行工具,用于从电子表格读取数据并导出到 Excel XLSB 工作簿。"绑定" 涵盖其他生态系统的绑定。
¥The "Complete Example" section includes a complete command-line tool for reading data from spreadsheets and exporting to Excel XLSB workbooks. "Bindings" covers bindings for other ecosystems.
集成详情
¥Integration Details
初始化 Duktape
¥Initialize Duktape
Duktape 不提供 global
变量。它可以在一行中创建:
¥Duktape does not provide a global
variable. It can be created in one line:
/* initialize */
duk_context *ctx = duk_create_heap_default();
/* duktape does not expose a standard "global" by default */
duk_eval_string_noresult(ctx, "var global = (function(){ return this; }).call(null);");
加载 SheetJS 脚本
¥Load SheetJS Scripts
SheetJS 独立脚本 可以在 Duktape 上下文中进行解析和评估。
¥The SheetJS Standalone scripts can be parsed and evaluated in a Duktape context.
可以通过从文件系统读取脚本并在 Duktape 上下文中进行评估来加载垫片和主库:
¥The shim and main libraries can be loaded by reading the scripts from the file system and evaluating in the Duktape context:
/* simple wrapper to read the entire script file */
static duk_int_t eval_file(duk_context *ctx, const char *filename) {
size_t len;
/* read script from filesystem */
FILE *f = fopen(filename, "rb");
if(!f) { duk_push_undefined(ctx); perror("fopen"); return 1; }
long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); }
char *buf = (char *)malloc(fsize * sizeof(char));
len = fread((void *) buf, 1, fsize, f);
fclose(f);
if(!buf) { duk_push_undefined(ctx); perror("fread"); return 1; }
/* load script into the context */
duk_push_lstring(ctx, (const char *)buf, (duk_size_t)len);
/* eval script */
duk_int_t retval = duk_peval(ctx);
/* cleanup */
duk_pop(ctx);
return retval;
}
// ...
duk_int_t res = 0;
if((res = eval_file(ctx, "shim.min.js")) != 0) { /* error handler */ }
if((res = eval_file(ctx, "xlsx.full.min.js")) != 0) { /* error handler */ }
要确认库已加载,可以检查 XLSX.version
:
¥To confirm the library is loaded, XLSX.version
can be inspected:
/* get version string */
duk_eval_string(ctx, "XLSX.version");
printf("SheetJS library version %s\n", duk_get_string(ctx, -1));
duk_pop(ctx);
读取文件
¥Reading Files
Duktape 本身支持 Buffer
,但应在处理前进行切片。假设 buf
是一个 C 字节数组,长度为 len
,此片段解析数据:
¥Duktape supports Buffer
natively but should be sliced before processing.
Assuming buf
is a C byte array, with length len
, this snippet parses data:
/* load C char array and save to a Buffer */
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, buf, len);
duk_put_global_string(ctx, "buf");
/* parse with SheetJS */
duk_eval_string_noresult(ctx, "workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});");
workbook
将是 JS 环境中的一个变量,可以使用各种 SheetJS API 函数进行检查。
¥workbook
will be a variable in the JS environment that can be inspected using
the various SheetJS API functions.
写入文件
¥Writing Files
duk_get_buffer_data
可以将 Buffer
对象数据拉入 C 代码中:
¥duk_get_buffer_data
can pull Buffer
object data into the C code:
/* write with SheetJS using type: "array" */
duk_eval_string(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})");
/* pull result back to C */
duk_size_t sz;
char *buf = (char *)duk_get_buffer_data(ctx, -1, sz);
/* discard result in duktape */
duk_pop(ctx);
生成的 buf
可以用 fwrite
写入文件。
¥The resulting buf
can be written to file with fwrite
.
完整示例
¥Complete Example
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | 版本 | 日期 |
---|---|---|
darwin-x64 | 2.7.0 | 2024-04-04 |
darwin-arm | 2.7.0 | 2024-05-23 |
win10-x64 | 2.7.0 | 2024-03-27 |
win11-arm | 2.7.0 | 2024-05-25 |
linux-x64 | 2.7.0 | 2024-03-21 |
linux-arm | 2.7.0 | 2024-05-23 |
该程序解析文件并打印第一个工作表中的 CSV 数据。它还生成 XLSB 文件并写入文件系统。
¥This program parses a file and prints CSV data from the first worksheet. It also generates an XLSB file and writes to the filesystem.
¥The flow diagram is displayed after the example steps
在 Windows 上,必须使用 Visual Studio "原生工具命令提示符"。
¥On Windows, the Visual Studio "Native Tools Command Prompt" must be used.
-
创建项目文件夹:
¥Create a project folder:
mkdir sheetjs-duk
cd sheetjs-duk
-
下载并解压 Duktape:
¥Download and extract Duktape:
- Linux/MacOS
- Windows
Windows 内置 tar
不支持 xz
存档。
¥The Windows built-in tar
does not support xz
archives.
命令必须在 WSL bash
内运行。
¥The commands must be run within WSL bash
.
在 mv
命令之后,退出 WSL。
¥After the mv
command, exit WSL.
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
tar -xJf duktape-2.7.0.tar.xz
mv duktape-2.7.0/src/*.{c,h} .
-
下载 SheetJS Standalone 脚本、shim 脚本和测试文件。将所有三个文件移动到项目目录:
¥Download the SheetJS Standalone script, shim script and test file. Move all three files to the project directory:
- Linux/MacOS
- Windows
如果 curl
命令失败,请运行 WSL bash
中的命令。
¥If the curl
command fails, run the commands within WSL bash
.
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
-
下载
sheetjs.duk.c
:¥Download
sheetjs.duk.c
:
curl -LO https://xlsx.nodejs.cn/duk/sheetjs.duk.c
-
编译独立的
sheetjs.duk
二进制文件¥Compile standalone
sheetjs.duk
binary
- Linux/MacOS
- Windows
gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm
GCC 可能会生成警告:
¥GCC may generate a warning:
duk_js_compiler.c:5628:13: warning: variable 'num_stmts' set but not used [-Wunused-but-set-variable]
duk_int_t num_stmts;
^
可以忽略此警告。
¥This warning can be ignored.
cl sheetjs.duk.c duktape.c /I .\
-
运行演示:
¥Run the demo:
- Linux/MacOS
- Windows
./sheetjs.duk pres.numbers
.\sheetjs.duk.exe 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.
流程图
¥Flow Diagram
绑定
¥Bindings
许多语言都存在绑定。由于这些绑定需要 "native" 代码,因此它们可能无法在每个平台上工作。
¥Bindings exist for many languages. As these bindings require "native" code, they may not work on every platform.
Duktape 源代码发行版包含一个单独的 Makefile,用于构建共享库。该库可以加载到其他程序中。
¥The Duktape source distribution includes a separate Makefile for building a shared library. This library can be loaded in other programs.
Blingos
Duktape 包含许多 "blingos"(类函数宏),这些宏不会包含在共享库中。必须手动扩展宏。
¥Duktape includes a number of "blingos" (function-like macros) which will not be included in the shared library. The macros must be manually expanded.
例如,duk_create_heap_default
定义如下:
¥For example, duk_create_heap_default
is defined as follows:
#define duk_create_heap_default() \
duk_create_heap(NULL, NULL, NULL, NULL, NULL)
duk_create_heap_default
blingo 不会在共享库中定义。相反,必须直接调用 duk_create_heap
。使用 PHP FFI:
¥The duk_create_heap_default
blingo will not be defined in the shared library.
Instead, duk_create_heap
must be called directly. Using PHP FFI:
/* create new FFI object */
$ffi = FFI::cdef(/* ... arguments */);
/* call duk_create_heap directly */
$context = $ffi->duk_create_heap(null, null, null, null, null);
空指针
¥Null Pointers
在某些函数中必须使用 C NULL
指针。某些 FFI 实现具有与语言原生空值不同的特殊值。使用 Python,返回类型提示由 restype
属性指定:
¥The C NULL
pointer must be used in some functions. Some FFI implementations
have special values distinct from the language-native null value. Using Python,
return type hints are specified with the restype
property:
from ctypes import CDLL, c_void_p
duk = CDLL("libduktape.so")
duk.duk_create_heap.restype = c_void_p
context = duk.duk_create_heap(None, None, None, None, None)
PHP
Duktape 库没有官方 PHP 绑定。相反,此演示使用 Duktape 共享库的原始 FFI
接口 [^1]。
¥There is no official PHP binding to the Duktape library. Instead, this demo uses
the raw FFI
interface[^1] to the Duktape shared library.
SheetJSDuk.php
演示脚本解析文件,打印第一个工作表中的 CSV 行,并创建 XLSB 工作簿。
¥The SheetJSDuk.php
demo script parses a
file, prints CSV rows from the first worksheet, and creates a XLSB workbook.
PHP 演示
¥PHP Demo
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | 版本 | PHP | 日期 |
---|---|---|---|
darwin-x64 | 2.7.0 | 8.3.4 | 2024-03-15 |
darwin-arm | 2.7.0 | 8.3.8 | 2024-06-30 |
linux-x64 | 2.7.0 | 8.2.7 | 2024-03-21 |
linux-arm | 2.7.0 | 8.2.18 | 2024-05-25 |
-
确保
php
已安装并在系统路径上可用¥Ensure
php
is installed and available on the system path -
找到
php.ini
文件:¥Find the
php.ini
file:
php --ini
以下输出来自上次 macOS 测试:
¥The following output is from the last macOS test:
Configuration File (php.ini) Path: /usr/local/etc/php/8.3
Loaded Configuration File: /usr/local/etc/php/8.3/php.ini
Scan for additional .ini files in: /usr/local/etc/php/8.3/conf.d
Additional .ini files parsed: /usr/local/etc/php/8.3/conf.d/ext-opcache.ini
-
编辑
php.ini
配置文件。¥Edit the
php.ini
configuration file.
配置中应出现以下行:
¥The following line should appear in the configuration:
extension=ffi
如果该行以 ;
为前缀,请删除分号。如果该行未出现在文件中,请将其添加到末尾。
¥If this line is prefixed with a ;
, remove the semicolon. If this line does not
appear in the file, add it to the end.
在 Linux 和 macOS 上,文件可能归 root
用户所有。如果使用普通用户账户写入文件失败,请使用 sudo
启动文本编辑器。
¥On Linux and macOS, the file may be owned by the root
user. If writing the
file fails with a normal user account, use sudo
to launch the text editor.
-
构建 Duktape 共享库:
¥Build the Duktape shared library:
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
tar -xJf duktape-2.7.0.tar.xz
cd duktape-2.7.0
make -f Makefile.sharedlibrary
cd ..
-
将共享库复制到当前文件夹。上次测试演示时,共享库文件名因平台而异:
¥Copy the shared library to the current folder. When the demo was last tested, the shared library file name differed by platform:
OS | name |
---|---|
达尔文 | libduktape.207.20700.so |
Linux | libduktape.so.207.20700 |
cp duktape-*/libduktape.* .
-
下载 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
-
下载
SheetJSDuk.php
:¥Download
SheetJSDuk.php
:
curl -LO https://xlsx.nodejs.cn/duk/SheetJSDuk.php
-
编辑
SheetJSDuk.php
脚本。¥Edit the
SheetJSDuk.php
script.
$sofile
变量声明库的路径:
¥The $sofile
variable declares the path to the library:
<?php
$sofile = './libduktape.207.20700.so';
- MacOS
- Linux
库的名称是 libduktape.207.20700.so
:
¥The name of the library is libduktape.207.20700.so
:
$sofile = './libduktape.207.20700.so';
库的名称是 libduktape.so.207.20700
:
¥The name of the library is libduktape.so.207.20700
:
$sofile = './libduktape.so.207.20700';
-
运行脚本:
¥Run the script:
php SheetJSDuk.php 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.
Python
Duktape 库没有官方的 Python 绑定。相反,此演示使用 Duktape 共享库的原始 ctypes
接口 [^2]。
¥There is no official Python binding to the Duktape library. Instead, this demo
uses the raw ctypes
interface[^2] to the Duktape shared library.
Python 演示
¥Python Demo
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | 版本 | Python | 日期 |
---|---|---|---|
darwin-x64 | 2.7.0 | 3.12.2 | 2024-03-15 |
darwin-arm | 2.7.0 | 3.12.3 | 2024-06-30 |
linux-x64 | 2.7.0 | 3.11.3 | 2024-03-21 |
linux-arm | 2.7.0 | 3.11.2 | 2024-05-25 |
-
确保
python
已安装并且在系统路径上可用。¥Ensure
python
is installed and available on the system path. -
构建 Duktape 共享库:
¥Build the Duktape shared library:
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
tar -xJf duktape-2.7.0.tar.xz
cd duktape-2.7.0
make -f Makefile.sharedlibrary
cd ..
-
将共享库复制到当前文件夹。上次测试演示时,共享库文件名因平台而异:
¥Copy the shared library to the current folder. When the demo was last tested, the shared library file name differed by platform:
OS | name |
---|---|
达尔文 | libduktape.207.20700.so |
Linux | libduktape.so.207.20700 |
cp duktape-*/libduktape.* .
-
下载 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
-
下载
SheetJSDuk.py
:¥Download
SheetJSDuk.py
:
curl -LO https://xlsx.nodejs.cn/duk/SheetJSDuk.py
-
编辑
SheetJSDuk.py
脚本。¥Edit the
SheetJSDuk.py
script.
lib
变量声明库的路径:
¥The lib
variable declares the path to the library:
#!/usr/bin/env python3
lib = "libduktape.207.20700.so"
- MacOS
- Linux
库的名称是 libduktape.207.20700.so
:
¥The name of the library is libduktape.207.20700.so
:
lib = "libduktape.207.20700.so"
库的名称是 libduktape.so.207.20700
:
¥The name of the library is libduktape.so.207.20700
:
lib = "libduktape.so.207.20700"
-
运行脚本:
¥Run the script:
python3 SheetJSDuk.py 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.
在一些测试中,该命令失败并出现 OSError
消息。
¥In some tests, the command failed with an OSError
message.
解决方法是将 ./
明确添加到 SheetJSDuk.py
中的 lib
变量:
¥The fix is to explicitly add ./
to the lib
variable in SheetJSDuk.py
:
- MacOS
- Linux
库的名称是 libduktape.207.20700.so
:
¥The name of the library is libduktape.207.20700.so
:
lib = "./libduktape.207.20700.so"
库的名称是 libduktape.so.207.20700
:
¥The name of the library is libduktape.so.207.20700
:
lib = "./libduktape.so.207.20700"
Zig
优秀的开源软件会随着用户测试和报告而不断成长。任何问题都应报告给 Zig 项目以进行进一步诊断。
¥Great open source software grows with user tests and reports. Any issues should be reported to the Zig project for further diagnosis.
Zig 编译
¥Zig Compilation
主 Duktape 代码可以添加到 Zig 构建管道中。
¥The main Duktape code can be added to the Zig build pipeline.
以下解释已针对 Zig 0.12.0 进行验证。
¥The following explanation was verified against Zig 0.12.0.
由于 Zig C 集成的限制,必须将 Duktape src
文件夹的路径添加到包含路径列表中:
¥Due to restrictions in the Zig C integration, the path to the Duktape src
folder must be added to the include path list:
const exe = b.addExecutable(.{
// ...
});
// this line is required to make @cInclude("duktape.h") work
exe.addIncludePath(.{ .path = "duktape-2.7.0/src" });
duktape.c
源文件必须添加到构建序列中。对于 Zig 版本 0.12.0,Duktape 必须使用标志 -std=c99 -fno-sanitize=undefined
进行编译并链接到 libc
和 libm
:
¥The duktape.c
source file must be added to the build sequence. For Zig version
0.12.0, Duktape must be compiled with flags -std=c99 -fno-sanitize=undefined
and linked against libc
and libm
:
const exe = b.addExecutable(.{
// ...
});
exe.addCSourceFile(.{:
.file = .{ .path = "duktape-2.7.0/src/duktape.c" },
.flags = &.{ "-std=c99", "-fno-sanitize=undefined" }
});
exe.linkSystemLibrary("c");
exe.linkSystemLibrary("m");
Zig 导入
¥Zig Import
可以使用 @cImport
指令导入 duktape.h
:
¥duktape.h
can be imported using the @cImport
directive:
const duktape = @cImport({
@cInclude("duktape.h");
});
导入后,可以从 duktape
范围引用许多 API 函数。例如,C 接口中的 duk_peval_string
将可用于使用名称 duktape.duk_peval_string
的 Zig 代码。
¥Once imported, many API functions can be referenced from the duktape
scope.
For example, duk_peval_string
in the C interface will be available to Zig code
using the name duktape.duk_peval_string
.
强烈建议使用 defer
并置分配和清理方法。例如,Duktape 上下文是使用 duk_create_heap
创建的,并使用 duk_destroy_heap
销毁的。后一个调用可以推迟:
¥It is strongly recommended to colocate allocations and cleanup methods using
defer
. For example, a Duktape context is created with duk_create_heap
and
destroyed with duk_destroy_heap
. The latter call can be deferred:
const ctx = duktape.duk_create_heap(null, null, null, null, null);
defer _ = duktape.duk_destroy_heap(ctx);
Zig 翻译器注意事项
¥Zig Translator Caveats
Zig 转换器无法正确处理 blingo void
角色。例如,duk_eval_string_noresult
是 duktape.h
中定义的类函数宏:
¥The Zig translator does not properly handle blingo void
casts. For example,
duk_eval_string_noresult
is a function-like macro defined in duktape.h
:
#define duk_eval_string_noresult(ctx,src) \
((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))
编译器将抛出涉及 anyopaque
(C void
) 的错误:
¥The compiler will throw an error involving anyopaque
(C void
):
error: opaque return type 'anyopaque' not allowed
blingo 执行 void
强制转换以抑制某些 C 编译器警告。Zig 中的精神等价物是分配给 _
。
¥The blingo performs a void
cast to suppress certain C compiler warnings. The
spiritual equivalent in Zig is to assign to _
.
duk_eval_raw
方法和每个编译时常量在 duktape
范围内可用。手动翻译如下:
¥The duk_eval_raw
method and each compile-time constant are available in the
duktape
scope. A manual translation is shown below:
_ = duktape.duk_eval_raw(ctx, src, 0, 0 | duktape.DUK_COMPILE_EVAL | duktape.DUK_COMPILE_NOSOURCE | duktape.DUK_COMPILE_STRLEN | duktape.DUK_COMPILE_NORESULT | duktape.DUK_COMPILE_NOFILENAME);
Zig 演示
¥Zig Demo
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | 版本 | Zig | 日期 |
---|---|---|---|
darwin-x64 | 2.7.0 | 0.11.0 | 2024-03-10 |
darwin-arm | 2.7.0 | 0.12.0 | 2024-05-23 |
win10-x64 | 2.7.0 | 0.11.0 | 2024-03-10 |
win11-arm | 2.7.0 | 0.12.0 | 2024-05-25 |
linux-x64 | 2.7.0 | 0.12.0 | 2024-04-25 |
linux-arm | 2.7.0 | 0.12.0 | 2024-05-25 |
在 Windows 上,由于 WSL 和 PowerShell 之间不兼容,某些命令必须在 WSL Bash 中运行。
¥On Windows, due to incompatibilities between WSL and PowerShell, some commands must be run in WSL Bash.
-
创建一个新的项目文件夹:
¥Create a new project folder:
mkdir sheetjs-zig
cd sheetjs-zig
-
从 https://ziglang.org/download/ 下载 Zig 0.12.0 并解压到项目文件夹中。
¥Download Zig 0.12.0 from https://ziglang.org/download/ and extract to the project folder.
- MacOS
- Linux
- Windows
对于 X64 Mac:
¥For X64 Mac:
curl -LO https://ziglang.org/download/0.12.0/zig-macos-x86_64-0.12.0.tar.xz
tar -xzf zig-macos-*.tar.xz
对于 ARM64 Mac:
¥For ARM64 Mac:
curl -LO https://ziglang.org/download/0.12.0/zig-macos-aarch64-0.12.0.tar.xz
tar -xzf zig-macos-*.tar.xz
对于 X64 Linux:
¥For X64 Linux:
curl -LO https://ziglang.org/download/0.12.0/zig-linux-x86_64-0.12.0.tar.xz
xz -d zig-linux-*.tar.xz
tar -xf zig-linux-*.tar
对于 AArch64 Linux:
¥For AArch64 Linux:
curl -LO https://ziglang.org/download/0.12.0/zig-linux-aarch64-0.12.0.tar.xz
xz -d zig-linux-*.tar.xz
tar -xf zig-linux-*.tar
以下命令应在 WSL bash 中运行。
¥The following commands should be run within WSL bash.
对于 X64 Windows:
¥For X64 Windows:
curl -LO https://ziglang.org/download/0.12.0/zig-windows-x86_64-0.12.0.zip
unzip zig-windows-x86_64-0.12.0.zip
对于 ARM64 Windows:
¥For ARM64 Windows:
curl -LO https://ziglang.org/download/0.12.0/zig-windows-aarch64-0.12.0.zip
unzip zig-windows-aarch64-0.12.0.zip
-
初始化一个项目:
¥Initialize a project:
- MacOS
- Linux
- Windows
./zig-*/zig init
./zig-*/zig init
以下命令应在 Powershell 中运行。
¥The following command should be run within Powershell.
.\zig-windows-*\zig.exe init
-
下载 Duktape 源代码并解压到当前目录中。在 Windows 上,命令应在 WSL 中运行:
¥Download the Duktape source and extract in the current directory. On Windows, the commands should be run within WSL:
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
tar -xJf duktape-2.7.0.tar.xz
-
下载 SheetJS Standalone 脚本、shim 脚本和测试文件。将所有三个文件移至
src
子目录:¥Download the SheetJS Standalone script, shim script and test file. Move all three files to the
src
subdirectory:
以下命令可以在 macOS 和 Linux 上的 shell 中运行。在 Windows 上,命令应在 WSL bash 中运行:
¥The following commands can be run within a shell on macOS and Linux. On Windows, the commands should be run within WSL bash:
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
mv *.js src
-
将高亮的行添加到
exe
定义之后的build.zig
中:¥Add the highlighted lines to
build.zig
just after theexe
definition:
const exe = b.addExecutable(.{
.name = "sheetjs-zig",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
exe.addCSourceFile(.{ .file = .{ .path = "duktape-2.7.0/src/duktape.c" }, .flags = &.{ "-std=c99", "-fno-sanitize=undefined" } });
exe.addIncludePath(.{ .path = "duktape-2.7.0/src" });
exe.linkSystemLibrary("c");
exe.linkSystemLibrary("m");
-
下载
main.zig
并替换src/main.zig
。应在 WSL bash 或 macOS 或 Linux 终端中运行以下命令:¥Download
main.zig
and replacesrc/main.zig
. The following command should be run in WSL bash or the macOS or Linux terminal:
curl -L -o src/main.zig https://xlsx.nodejs.cn/duk/main.zig
-
构建并运行程序:
¥Build and run the program:
- MacOS
- Linux
- Windows
./zig-*/zig build run -- pres.numbers
./zig-*/zig build run -- pres.numbers
在 Arch Linux 和 HoloOS (Steam Deck) 上,编译可能会失败:
¥On Arch Linux and HoloOS (Steam Deck), compilation may fail:
zig build-exe sheetjs-zig Debug native: error: error: unable to create compilation: LibCStdLibHeaderNotFound
必须安装 glibc
和 linux-api-headers
:
¥glibc
and linux-api-headers
must be installed:
sudo pacman -Syu glibc linux-api-headers
此命令应在 PowerShell 中运行:
¥This command should be run in PowerShell:
.\zig-windows-*\zig.exe build run -- pres.numbers
此步骤构建并运行程序。生成的程序将放置在 zig-out/bin/
子目录中。
¥This step builds and runs the program. The generated program will be placed in
the zig-out/bin/
subdirectory.
它应该显示一些元数据以及第一个工作表中的 CSV 行。它还会生成 sheetjs.zig.xlsx
,可以使用 Excel 等电子表格编辑器打开它。
¥It should display some metadata along with CSV rows from the first worksheet.
It will also generate sheetjs.zig.xlsx
, which can be opened with a spreadsheet
editor such as Excel.
Perl
Duktape 的 Perl 绑定在 CPAN 上以 JavaScript::Duktape::XS
形式提供。
¥The Perl binding for Duktape is available as JavaScript::Duktape::XS
on CPAN.
Perl 绑定没有原始 Buffer
操作,因此使用 Base64 字符串。
¥The Perl binding does not have raw Buffer
ops, so Base64 strings are used.
Perl 演示
¥Perl Demo
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | 版本 | 日期 |
---|---|---|
darwin-x64 | 2.2.0 | 2024-03-15 |
darwin-arm | 2.2.0 | 2024-06-30 |
linux-x64 | 2.2.0 | 2024-03-21 |
linux-arm | 2.2.0 | 2024-05-25 |
-
确保
perl
和cpan
已安装并在系统路径上可用。¥Ensure
perl
andcpan
are installed and available on the system path. -
安装
JavaScript::Duktape::XS
库:¥Install the
JavaScript::Duktape::XS
library:
cpan install JavaScript::Duktape::XS
在某些系统上,必须以 root 用户身份运行该命令:
¥On some systems, the command must be run as the root user:
sudo cpan install JavaScript::Duktape::XS
-
下载
SheetJSDuk.pl
:¥Download
SheetJSDuk.pl
:
curl -LO https://xlsx.nodejs.cn/duk/SheetJSDuk.pl
-
下载 SheetJS ExtendScript 构建和测试文件:
¥Download the SheetJS ExtendScript build and test file:
curl -LO https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.extendscript.js
curl -LO https://xlsx.nodejs.cn/pres.xlsx
-
运行脚本:
¥Run the script:
perl SheetJSDuk.pl pres.xlsx
如果脚本成功,测试文件中的数据将打印在 CSV 行中。该脚本还将导出 SheetJSDuk.xlsb
。
¥If the script succeeded, the data in the test file will be printed in CSV rows.
The script will also export SheetJSDuk.xlsb
.
在某些测试运行中,该命令由于缺少 File::Slurp
而失败:
¥In some test runs, the command failed due to missing File::Slurp
:
Can't locate File/Slurp.pm in @INC (you may need to install the File::Slurp module)
修复方法是安装 File::Slurp
和 cpan
:
¥The fix is to install File::Slurp
with cpan
:
sudo cpan install File::Slurp
[^1]: 请参阅 PHP 文档中的 对外函数接口。
¥See Foreign Function Interface in the PHP documentation.
[^2]: 请参阅 Python 文档中的 ctypes
。
¥See ctypes
in the Python documentation.