Skip to main content

Electron

NodeJS 模块 可以从主线程或渲染器线程导入。

¥The NodeJS Module can be imported from the main or the renderer thread.

"完整示例" 创建一个应用,如下图所示:

¥The "Complete Example" creates an app that looks like the screenshots below:

WindowsmacOSLinux

Windows screenshot

macOS screenshot

Linux screenshot

集成详情

¥Integration Details

Electron 推出了 fs 模块。require('xlsx') 调用加载 CommonJS 模块,因此 XLSX.readFileXLSX.writeFile 在渲染器线程中工作。

¥Electron presents a fs module. The require('xlsx') call loads the CommonJS module, so XLSX.readFile and XLSX.writeFile work in the renderer thread.

读取文件

¥Reading Files

Electron 提供了 3 种不同的方式来读取文件,其中两种方式使用 Web API。

¥Electron offers 3 different ways to read files, two of which use Web APIs.

文件输入元素

¥File Input Element

文件输入元素自动映射到标准 Web API。

¥File input elements automatically map to standard Web APIs.

例如,假设页面上有一个文件输入元素:

¥For example, assuming a file input element on the page:

<input type="file" name="xlfile" id="xlf" />

事件处理程序将像处理 Web 事件一样处理该事件:

¥The event handler would process the event as if it were a web event:

async function handleFile(e) {
const file = e.target.files[0];
const data = await file.arrayBuffer();
/* data is an ArrayBuffer */
const workbook = XLSX.read(data);

/* DO SOMETHING WITH workbook HERE */
}
document.getElementById("xlf").addEventListener("change", handleFile, false);

拖放

¥Drag and Drop

拖放片段 适用于页面上的 DIV 元素。

¥The drag and drop snippet applies to DIV elements on the page.

例如,假设页面上有一个 DIV:

¥For example, assuming a DIV on the page:

<div id="drop">Drop a spreadsheet file here to see sheet data</div>

事件处理程序将像处理 Web 事件一样处理该事件:

¥The event handler would process the event as if it were a web event:

async function handleDrop(e) {
e.stopPropagation();
e.preventDefault();

const file = e.dataTransfer.files[0];
const data = await file.arrayBuffer();
/* data is an ArrayBuffer */
const workbook = XLSX.read(data);

/* DO SOMETHING WITH workbook HERE */
}
document.getElementById("drop").addEventListener("drop", handleDrop, false);

Electron API

XLSX.readFile 从文件系统读取工作簿。showOpenDialog 显示另存为对话框并返回选定的文件名。与 Web API 不同,showOpenDialog 流程可以由应用代码启动:

¥XLSX.readFile reads workbooks from the file system. showOpenDialog shows a Save As dialog and returns the selected file name. Unlike the Web APIs, the showOpenDialog flow can be initiated by app code:

/* from the renderer thread */
const electron = require('@electron/remote');

/* this function will show the open dialog and try to parse the workbook */
async function importFile() {
/* show Save As dialog */
const result = await electron.dialog.showOpenDialog({
title: 'Select a file',
filters: [{
name: "Spreadsheets",
extensions: ["xlsx", "xls", "xlsb", /* ... other formats ... */]
}]
});
/* result.filePaths is an array of selected files */
if(result.filePaths.length == 0) throw new Error("No file was selected!");
return XLSX.readFile(result.filePaths[0]);
}

showOpenDialog 最初返回一个路径数组:

¥showOpenDialog originally returned an array of paths:

var dialog = require('electron').remote.dialog;

function importFile(workbook) {
var result = dialog.showOpenDialog({ properties: ['openFile'] });
return XLSX.readFile(result[0]);
}

该方法在 Electron 6 中被重命名为 showOpenDialogSync

¥This method was renamed to showOpenDialogSync in Electron 6.

写入文件

¥Writing Files

XLSX.writeFile 将工作簿写入文件系统。showSaveDialog 显示另存为对话框并返回选定的文件名:

¥XLSX.writeFile writes workbooks to the file system. showSaveDialog shows a Save As dialog and returns the selected file name:

/* from the renderer thread */
const electron = require('@electron/remote');

/* this function will show the save dialog and try to write the workbook */
async function exportFile(workbook) {
/* show Save As dialog */
const result = await electron.dialog.showSaveDialog({
title: 'Save file as',
filters: [{
name: "Spreadsheets",
extensions: ["xlsx", "xls", "xlsb", /* ... other formats ... */]
}]
});
/* write file */
XLSX.writeFile(workbook, result.filePath);
}

showSaveDialog 最初返回选择的路径:

¥showSaveDialog originally returned the selected path:

var dialog = require('electron').remote.dialog;

function exportFile(workbook) {
var result = dialog.showSaveDialog();
XLSX.writeFile(workbook, result);
}

该方法在 Electron 6 中被重命名为 showSaveDialogSync

¥This method was renamed to showSaveDialogSync in Electron 6.

完整示例

¥Complete Example

测试部署

本 demo 在以下环境下进行了测试:

¥This demo was tested in the following environments:

操作系统和版本架构Electron日期
macOS 14.4darwin-x6429.1.42024-03-15
macOS 14.5darwin-arm30.0.82024-05-28
Windows 10win10-x6431.2.02024-07-12
视窗 11win11-x6431.2.02024-08-18
视窗 11win11-arm30.0.82024-05-28
Linux(全息操作系统)linux-x6429.1.42024-03-21
Linux(Debian)linux-arm30.0.82024-05-28

该演示包括一个拖放框以及一个文件输入框,镜像了 SheetJS 数据预览在线演示

¥This demo includes a drag-and-drop box as well as a file input box, mirroring the SheetJS Data Preview Live Demo

该演示中的核心数据是一个可编辑的 HTML 表格。读者使用 sheet_to_html(带有 editable:true 选项)构建表格,作者使用 table_to_book 抓取表格。

¥The core data in this demo is an editable HTML table. The readers build up the table using sheet_to_html (with editable:true option) and the writers scrape the table using table_to_book.

该演示项目已连接至 electron-forge 以构建独立的二进制文件。

¥The demo project is wired for electron-forge to build the standalone binary.

  1. 下载演示文件:

    ¥Download the demo files:

右键单击每个链接并选择 "保存链接为..."。左键单击链接将尝试在浏览器中加载该页面。目标是保存文件内容。

¥Right-click each link and select "Save Link As...". Left-clicking a link will try to load the page in your browser. The goal is to save the file contents.

这些指令可以在终端 (bash) 或命令提示符窗口中运行:

¥These instructions can be run in a Terminal (bash) or Command Prompt window:

mkdir sheetjs-electron
cd sheetjs-electron
curl -LO https://xlsx.nodejs.cn/electron/package.json
curl -LO https://xlsx.nodejs.cn/electron/main.js
curl -LO https://xlsx.nodejs.cn/electron/index.html
curl -LO https://xlsx.nodejs.cn/electron/index.js
  1. 安装依赖:

    ¥Install dependencies:

npm install
  1. 要验证应用是否有效,请在测试环境中运行:

    ¥To verify the app works, run in the test environment:

npx -y electron .

应用将运行。

¥The app will run.

  1. 要构建独立应用,请运行构建器:

    ¥To build a standalone app, run the builder:

npm run make

这将在 out\make 文件夹中创建一个包和一个独立的二进制文件。

¥This will create a package in the out\make folder and a standalone binary.

在 Linux 上,打包步骤可能需要额外的依赖 [^1]

¥On Linux, the packaging step may require additional dependencies[^1]

上次在 Windows ARM 上测试演示时,生成的二进制文件面向 x64。该程序将在 ARM64 Windows 上运行。

¥When the demo was last tested on Windows ARM, the generated binary targeted x64. The program will run on ARM64 Windows.

测试

¥Testing

  1. 下载 测试文件 pres.numbers

    ¥Download the test file pres.numbers

  2. 启动生成的应用:

    ¥Launch the generated application:

架构命令
darwin-x64open ./out/sheetjs-electron-darwin-x64/sheetjs-electron.app
darwin-armopen ./out/sheetjs-electron-darwin-arm64/sheetjs-electron.app
win10-x64.\out\sheetjs-electron-win32-x64\sheetjs-electron.exe
win11-arm.\out\sheetjs-electron-win32-x64\sheetjs-electron.exe
linux-x64./out/sheetjs-electron-linux-x64/sheetjs-electron
linux-arm./out/sheetjs-electron-linux-arm64/sheetjs-electron

Electron API

  1. 单击 "单击此处从你的计算机中选择一个文件"。使用文件选择器,导航至“下载”文件夹并选择 pres.numbers

    ¥Click "Click here to select a file from your computer". With the file picker, navigate to the Downloads folder and select pres.numbers.

应用应在表格中显示数据。

¥The application should show data in a table.

  1. 单击 "导出数据!",然后在弹出窗口中单击 "保存"。默认情况下,它将尝试写入下载文件夹中的 Untitled.xls

    ¥Click "Export Data!" and click "Save" in the popup. By default, it will try to write to Untitled.xls in the Downloads folder.

在某些测试中,对话框没有默认名称。

¥In some tests, the dialog did not have a default name.

如果没有默认名称,则输入 Untitled.xls,然后单击 "保存"。

¥If there is no default name, enter Untitled.xls and click "Save".

导出数据后,应用将显示一个弹出窗口。在电子表格编辑器中打开文件,并将数据与应用中显示的表格进行比较。

¥The app will show a popup once the data is exported. Open the file in a spreadsheet editor and compare the data to the table shown in the application.

拖放

¥Drag and Drop

  1. 关闭应用,结束终端进程并重新启动(参见步骤 6)

    ¥Close the application, end the terminal process and re-launch (see step 6)

  2. 在文件资源管理器或查找器窗口中打开“下载”文件夹。

    ¥Open the Downloads folder in a file explorer or finder window.

  3. 单击 pres.numbers 文件并将其从“下载”文件夹拖动到带边框的 "删除电子表格文件" 框。应显示文件数据。

    ¥Click and drag the pres.numbers file from the Downloads folder to the bordered "Drop a spreadsheet file" box. The file data should be displayed.

文件输入元素

¥File Input Element

  1. 关闭应用,结束终端进程并重新启动(参见步骤 6)

    ¥Close the application, end the terminal process and re-launch (see step 6)

  2. 单击 "选择文件"。使用文件选择器,导航至“下载”文件夹并选择 pres.numbers

    ¥Click "Choose File". With the file picker, navigate to the Downloads folder and select pres.numbers.

Electron 重大变化

¥Electron Breaking Changes

该演示的第一个版本使用 Electron 1.7.5。当前演示包含 Electron 30.0.8 所需的更改。

¥The first version of this demo used Electron 1.7.5. The current demo includes the required changes for Electron 30.0.8.

库中没有特定于 Electron 的解决方法,但 Electron 多次破坏了向后兼容性。变更摘要如下。

¥There are no Electron-specific workarounds in the library, but Electron broke backwards compatibility multiple times. A summary of changes is noted below.

Electron 6 更改了 dialog API 方法的返回类型。旧的 dialog 方法已重命名:

¥Electron 6 changed the return types of dialog API methods. The old dialog methods have been renamed:

电子 1 - 5电子 6
showOpenDialogshowOpenDialogSync
showSaveDialogshowSaveDialogSync
此更改未正确记录!

Electron 9 及更高版本需要优先级 nodeIntegration: true 才能在渲染器进程中使用 require('xlsx')

¥Electron 9 and later require the preference nodeIntegration: true in order to require('xlsx') in the renderer process.

Electron 12 及更高版本也需要 worldSafeExecuteJavascript: truecontextIsolation: true

¥Electron 12 and later also require worldSafeExecuteJavascript: true and contextIsolation: true.

Electron 14 及更高版本必须使用 @electron/remote 而不是 remote。需要调用 initialize 才能在窗口中启用开发者工具。

¥Electron 14 and later must use @electron/remote instead of remote. An initialize call is required to enable Developer Tools in the window.

[^1]: 请参阅 Electron Forge 文档中的 "创客"。在 Linux 上,演示生成 rpmdeb 可分发文件。在 Arch Linux 和 Steam Deck 上,sudo pacman -Syu rpm-tools dpkg fakeroot 安装了所需的软件包。

¥See "Makers" in the Electron Forge documentation. On Linux, the demo generates rpm and deb distributables. On Arch Linux and the Steam Deck, sudo pacman -Syu rpm-tools dpkg fakeroot installed required packages.