使用 Jint 的 .NET 中的工作表
Jint[^1] 是 .NET Standard 和 .NET Core 的 JavaScript 解释器。它内置了对 .NET byte[]
和 ES6 Uint8Array
二进制数据的支持。
¥Jint[^1] is a JavaScript interpreter for .NET Standard and .NET Core. It has
built-in support for binary data with .NET byte[]
and ES6 Uint8Array
.
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
该演示使用 Jint 和 SheetJS 来读取和写入电子表格。我们将探讨如何在 Jint 引擎中加载 SheetJS、与 C# 程序交换二进制数据以及处理电子表格和结构化数据。
¥This demo uses Jint and SheetJS to read and write spreadsheets. We'll explore how to load SheetJS in the Jint engine, exchange binary data with a C# program, and process spreadsheets and structured data.
"集成示例" 部分包括一个完整的命令行工具,用于读取任意工作簿并将数据写入 XLSB(Excel 2007+ 二进制格式)工作簿。
¥The "Integration Example" section includes a complete command-line tool for reading arbitrary workbooks and writing data to XLSB (Excel 2007+ Binary Format) workbooks.
dotnet
命令嵌入遥测技术。
¥The dotnet
command embeds telemetry.
DOTNET_CLI_TELEMETRY_OPTOUT
环境变量应设置为 1
。
¥The DOTNET_CLI_TELEMETRY_OPTOUT
environment variable should be set to 1
.
"平台配置" 包含有关在支持的平台上设置环境变量的说明。
¥"Platform Configuration" includes instructions for setting the environment variable on supported platforms.
集成详情
¥Integration Details
大多数集成功能都没有记录。此说明基于版本 3.1.0
。
¥Most of the integration functions are not documented. This explanation is based
on version 3.1.0
.
SheetJS 独立脚本 可以在 Jint 引擎实例中进行解析和评估。
¥The SheetJS Standalone scripts can be parsed and evaluated in a Jint engine instance.
初始化 Jint
¥Initialize Jint
可以在一行中创建 Jint.Engine
对象:
¥A Jint.Engine
object can be created in one line:
var engine = new Jint.Engine();
Jint 不公开 NodeJS global
,但提供 globalThis
。使用 Jint.Engine#Evaluate
,可以创建 global
全局变量:
¥Jint does not expose the NodeJS global
but does provide globalThis
. Using
Jint.Engine#Evaluate
, a global
global variable can be created:
JS 代码是
¥The JS code is
global = globalThis;
engine.Evaluate("global = globalThis");
加载 SheetJS 脚本
¥Load SheetJS Scripts
可以通过使用 System.IO.File.ReadAllText
从文件系统读取脚本并在 Jint 引擎实例中进行评估来加载主库:
¥The main library can be loaded by reading the scripts from the file system with
System.IO.File.ReadAllText
and evaluating in the Jint engine instance:
/* read and evaluate the shim script */
string src = System.IO.File.ReadAllText("shim.min.js");
engine.Evaluate(src);
/* read and evaluate the main library */
engine.Evaluate(System.IO.File.ReadAllText("xlsx.full.min.js"));
要确认库已加载,可以检查 XLSX.version
:
¥To confirm the library is loaded, XLSX.version
can be inspected:
Console.WriteLine("SheetJS version {0}", engine.Evaluate("XLSX.version"));
Jint Evaluate
方法返回通用 Jint.Native.JsValue
对象。
¥The Jint Evaluate
method returns a generic Jint.Native.JsValue
object.
当 JS 表达式返回字符串时,JsValue
对象是 Jint.Native.JsString
的实例。C# ToString
将返回基础 string
值。
¥When the JS expression returns a string, the JsValue
object is an instance of
Jint.Native.JsString
. C# ToString
will return the underlying string
value.
读取文件
¥Reading Files
在 C# 中,System.IO.File.ReadAllBytes
将文件数据读取到 byte[]
字节数组中:
¥In C#, System.IO.File.ReadAllBytes
reads file data into a byte[]
byte array:
string filename = "pres.xlsx";
byte[] buf = File.ReadAllBytes(filename);
Jint 本身支持字节数组的 Uint8Array
构造:
¥Jint natively supports Uint8Array
construction from the byte array:
Jint.Native.JsValue u8 = engine.Intrinsics.Uint8Array.Construct(buf);
Jint.Engine#SetValue
会将 Uint8Array
分配给 JS 中的作用域变量:
¥Jint.Engine#SetValue
will assign the Uint8Array
to a scope variable in JS:
engine.SetValue("buf", u8);
可以使用 SheetJS read
方法 [^2] 从 JS 中解析 buf
变量:
¥The buf
variable can be parsed from JS with the SheetJS read
method[^2]:
JS 代码是
¥The JS code is
var wb = XLSX.read(buf);
engine.Evaluate("var wb = XLSX.read(buf);");
wb
是一个 SheetJS 工作簿对象。"SheetJS 数据模型" 部分描述了对象结构,"API 参考" 部分描述了各种辅助函数。
¥wb
is a SheetJS workbook object. The "SheetJS Data Model" section
describes the object structure and the "API Reference" section
describes various helper functions.
写入文件
¥Writing Files
SheetJS write
方法 [^3] 可以编写工作簿。选项 type: "buffer"
指示库生成 Uint8Array
对象。
¥The SheetJS write
method[^3] can write workbooks. The option type: "buffer"
instructs the library to generate Uint8Array
objects.
导出为 XLSB 格式的 JS 代码为:
¥The JS code for exporting to the XLSB format is:
var u8 = XLSX.write(wb, {bookType: 'xlsb', type: 'buffer'});
可以使用 bookType
选项 [^4] 更改文件格式
¥The file format can be changed with the bookType
option[^4]
Jint.Native.JsValue xlsb = engine.Evaluate("XLSX.write(wb, {bookType: 'xlsb', type: 'buffer'})");
xlsb
代表 Uint8Array
。xlsb.AsUint8Array()
将字节作为 byte[]
数组返回,可以使用 System.IO.File.WriteAllBytes
导出:
¥xlsb
represents a Uint8Array
. xlsb.AsUint8Array()
returns the bytes as a
byte[]
array which can be exported with System.IO.File.WriteAllBytes
:
byte[] outfile = xlsb.AsUint8Array();
System.IO.File.WriteAllBytes("SheetJSJint.xlsb", outfile);
集成示例
¥Integration Example
该演示在以下部署中进行了测试:
¥This demo was tested in the following deployments:
架构 | Jint | 日期 |
---|---|---|
darwin-x64 | 3.0.1 | 2024-03-15 |
darwin-arm | 3.1.2 | 2024-05-25 |
win10-x64 | 3.1.0 | 2024-04-17 |
win11-arm | 3.1.2 | 2024-05-25 |
linux-x64 | 3.1.0 | 2024-04-25 |
linux-arm | 3.1.2 | 2024-05-25 |
平台配置
¥Platform Configuration
-
将
DOTNET_CLI_TELEMETRY_OPTOUT
环境变量设置为1
。¥Set the
DOTNET_CLI_TELEMETRY_OPTOUT
environment variable to1
.
How to disable telemetry (click to hide)
- Linux/MacOS
- Windows
将以下行添加到 .profile
、.bashrc
和 .zshrc
:
¥Add the following line to .profile
, .bashrc
and .zshrc
:
export DOTNET_CLI_TELEMETRY_OPTOUT=1
关闭并重新启动终端以加载更改。
¥Close and restart the Terminal to load the changes.
在搜索栏中输入 env
,然后选择 "编辑系统环境变量"。
¥Type env
in the search bar and select "Edit the system environment variables".
在新窗口中,单击 "环境变量..." 按钮。
¥In the new window, click the "Environment Variables..." button.
在新窗口中,查找 "系统变量" 部分并单击 "新的..."
¥In the new window, look for the "System variables" section and click "New..."
将 "变量名" 设置为 DOTNET_CLI_TELEMETRY_OPTOUT
,并将值设置为 1
。
¥Set the "Variable name" to DOTNET_CLI_TELEMETRY_OPTOUT
and the value to 1
.
在每个窗口(3 个窗口)中单击 "OK",然后重新启动计算机。
¥Click "OK" in each window (3 windows) and restart your computer.
-
安装.NET
¥Install .NET
Installation Notes (click to show)
For macOS x64 and ARM64, install the dotnet-sdk
Cask with Homebrew:
brew install --cask dotnet-sdk
For Steam Deck Holo and other Arch Linux x64 distributions, the dotnet-sdk
and
dotnet-runtime
packages should be installed using pacman
:
sudo pacman -Syu dotnet-sdk dotnet-runtime
https://dotnet.microsoft.com/en-us/download/dotnet/6.0 is the official source for Windows and ARM64 Linux versions.
-
在 macOS 中打开新的终端窗口或在 Windows 中打开 PowerShell 窗口。
¥Open a new Terminal window in macOS or PowerShell window in Windows.
基础项目
¥Base Project
-
使用
dotnet
工具创建一个新文件夹SheetJSJint
和一个新项目:¥Create a new folder
SheetJSJint
and a new project using thedotnet
tool:
mkdir SheetJSJint
cd SheetJSJint
dotnet new console
dotnet run
-
使用 NuGet 工具添加 Jint:
¥Add Jint using the NuGet tool:
dotnet nuget add source https://www.myget.org/F/jint/api/v3/index.json
dotnet add package Jint --version 3.1.2
要验证 Jint 是否已安装,请将 Program.cs
替换为以下内容:
¥To verify Jint is installed, replace Program.cs
with the following:
var engine = new Jint.Engine();
Console.WriteLine("Hello {0}", engine.Evaluate("'Sheet' + 'JS'"));
保存后运行程序:
¥After saving, run the program:
dotnet run
终端应显示 Hello SheetJS
¥The terminal should display Hello SheetJS
添加 SheetJS
¥Add SheetJS
-
下载 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.xlsx
-
将
Program.cs
替换为以下内容:¥Replace
Program.cs
with the following:
var engine = new Jint.Engine();
engine.Evaluate("global = globalThis;");
engine.Evaluate(File.ReadAllText("shim.min.js"));
engine.Evaluate(File.ReadAllText("xlsx.full.min.js"));
Console.WriteLine("SheetJS version {0}", engine.Evaluate("XLSX.version"));
保存后运行程序:
¥After saving, run the program:
dotnet run
The terminal should display SheetJS version 0.20.3
读写文件
¥Read and Write Files
-
将
Program.cs
替换为以下内容:¥Replace
Program.cs
with the following:
using Jint;
/* Initialize Jint */
var engine = new Jint.Engine();
engine.Evaluate("global = globalThis;");
/* Load SheetJS Scripts */
engine.Evaluate(File.ReadAllText("shim.min.js"));
engine.Evaluate(File.ReadAllText("xlsx.full.min.js"));
Console.WriteLine("SheetJS version {0}", engine.Evaluate("XLSX.version"));
/* Read and Parse File */
byte[] filedata = File.ReadAllBytes(args[0]);
Jint.Native.JsValue u8 = engine.Intrinsics.Uint8Array.Construct(filedata);
engine.SetValue("buf", u8);
engine.Evaluate("var wb = XLSX.read(buf);");
/* Print CSV of first worksheet*/
engine.Evaluate("var ws = wb.Sheets[wb.SheetNames[0]];");
Jint.Native.JsValue csv = engine.Evaluate("XLSX.utils.sheet_to_csv(ws)");
Console.Write(csv);
/* Generate XLSB file and save to SheetJSJint.xlsb */
Jint.Native.JsValue xlsb = engine.Evaluate("XLSX.write(wb, {bookType: 'xlsb', type: 'buffer'})");
File.WriteAllBytes("SheetJSJint.xlsb", xlsb.AsUint8Array());
保存后,运行程序并将测试文件名作为参数传递:
¥After saving, run the program and pass the test file name as an argument:
dotnet run pres.xlsx
如果成功,程序会将第一张表的内容打印为 CSV 行。它还将创建可以在 Excel 或其他电子表格编辑器中打开的 SheetJSJint.xlsb
。
¥If successful, the program will print the contents of the first sheet as CSV
rows. It will also create SheetJSJint.xlsb
which can be opened in Excel or
another spreadsheet editor.
在不带文件名参数的情况下运行 dotnet run
将显示错误:
¥Running dotnet run
without the filename argument will show an error:
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Program.<Main>$(String[] args) in C:\Users\Me\SheetJSJint\Program.cs:line 13
该命令必须使用指定工作簿名称的参数运行:
¥The command must be run with an argument specifying the name of the workbook:
dotnet run pres.xlsx
如果省略 using Jint;
指令,构建将失败:
¥If the using Jint;
directive is omitted, the build will fail:
'JsValue' does not contain a definition for 'AsUint8Array' and no accessible extension method 'AsUint8Array' accepting a first argument of type 'JsValue' could be found
独立应用
¥Standalone Application
-
查找你的平台 [^5] 的运行时标识符(RID)。下面列出了测试平台的 RID 值:
¥Find the runtime identifier (RID) for your platform[^5]. The RID values for tested platforms are listed below:
平台 | RID |
---|---|
英特尔 Mac | osx-x64 |
ARM64 苹果电脑 | osx-arm64 |
Windows 10 (x64) | win10-x64 |
Windows 11(ARM) | win-arm64 |
Linux (x64) | linux-x64 |
Linux(ARM) | linux-arm64 |
-
构建独立应用。
¥Build the standalone application.
Tested platforms (click to hide)
- Intel Mac
- ARM64 Mac
- Linux x64
- Linux ARM
- Windows x64
- Windows ARM
对于 Intel Mac,RID 为 osx-x64
,命令为
¥For Intel Mac, the RID is osx-x64
and the command is
dotnet publish -c Release -r osx-x64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true
对于 Apple Silicon,RID 为 osx-arm64
,命令为
¥For Apple Silicon, the RID is osx-arm64
and the command is
dotnet publish -c Release -r osx-arm64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true
对于 x64 Linux,RID 为 linux-x64
,命令为
¥For x64 Linux, the RID is linux-x64
and the command is
dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true
对于 x64 Linux,RID 为 linux-arm64
,命令为
¥For x64 Linux, the RID is linux-arm64
and the command is
dotnet publish -c Release -r linux-arm64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true
对于 Windows 10 x64,RID 为 win10-x64
,命令为:
¥For Windows 10 x64, the RID is win10-x64
and the command is:
dotnet publish -c Release -r win10-x64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true
对于 Windows 11 ARM64,RID 为 win-arm64
,命令为:
¥For Windows 11 ARM64, the RID is win-arm64
and the command is:
dotnet publish -c Release -r win-arm64 --self-contained true -p:PublishSingleFile=true -p:PublishTrimmed=true
-
将生成的可执行文件复制到项目目录。
¥Copy the generated executable to the project directory.
二进制文件名称将为 SheetJSJint
或 SheetJSJint.exe
,具体取决于操作系统。
¥The binary name will be SheetJSJint
or SheetJSJint.exe
depending on OS.
步骤 9 输出的最后一行将打印输出文件夹。
¥The last line of the output from Step 9 will print the output folder.
Tested platforms (click to hide)
- Intel Mac
- ARM64 Mac
- Linux x64
- Linux ARM
- Windows x64
- Windows ARM
对于 Intel Mac,RID 为 osx-x64
,命令为:
¥For Intel Mac, the RID is osx-x64
and the command is:
cp bin/Release/net*/osx-x64/publish/SheetJSJint .
对于 Apple Silicon,RID 为 osx-arm64
,命令为:
¥For Apple Silicon, the RID is osx-arm64
and the command is:
cp bin/Release/net6.0/osx-arm64/publish/SheetJSJint .
对于 x64 Linux,RID 为 linux-x64
,命令为
¥For x64 Linux, the RID is linux-x64
and the command is
cp bin/Release/net*/linux-x64/publish/SheetJSJint .
对于 x64 Linux,RID 为 linux-arm64
,命令为
¥For x64 Linux, the RID is linux-arm64
and the command is
cp bin/Release/net6.0/linux-arm64/publish/SheetJSJint .
对于 Windows 10 x64,RID 为 win10-x64
,命令为:
¥For Windows 10 x64, the RID is win10-x64
and the command is:
copy .\bin\Release\net6.0\win10-x64\publish\SheetJSJint.exe .
在某些测试运行中,copy
命令失败并显示一条明确的消息:
¥In some test runs, the copy
command failed with a clear message:
The system cannot find the path specified.
正确的命令是
¥The correct command was
copy .\bin\x64\Release\net6.0\win10-x64\publish\SheetJSJint.exe .
对于 Windows 11 ARM64,RID 为 win-arm64
,命令为:
¥For Windows 11 ARM64, the RID is win-arm64
and the command is:
copy .\bin\Release\net6.0\win-arm64\publish\SheetJSJint.exe .
-
运行生成的命令。
¥Run the generated command.
- Linux/MacOS
- Windows
./SheetJSJint pres.xlsx
.\SheetJSJint pres.xlsx
[^1]: Jint 项目推荐 "MyGet" 服务。据开发者称,"NuGet" 包 是 "偶尔发表"。
¥The Jint project recommends the "MyGet" service. According to the developers, the "NuGet" package is "occasionally published".
[^2]: 见 read
于 "读取文件"
[^3]: 见 write
于 "写入文件"
[^4]: 有关 bookType
的详细信息,请参阅 "支持的输出格式" 于 "写入文件"
¥See "Supported Output Formats" in "Writing Files" for details on bookType
[^5]: 请参阅 .NET 文档中的 ".NET RID 目录"
¥See ".NET RID Catalog" in the .NET documentation