Skip to main content

NodeJS

软件包 tarball 在 https://cdn.sheetjs.com 上可用。

¥Package tarballs are available on https://cdn.sheetjs.com.

https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz is the URL for version 0.20.3

安装

¥Installation

可以使用包管理器直接安装 Tarball:

¥Tarballs can be directly installed using a package manager:

yarn remove xlsx
yarn add https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

Yarn 的较新版本可能会引发错误:

¥Newer releases of Yarn may throw an error:

Usage Error: It seems you are trying to add a package using a https:... url; we now require package names to be explicitly specified.
Try running the command again with the package name prefixed: yarn add my-package@https:...

解决方法是将 xlsx@ 添加到 URL 前面:

¥The workaround is to prepend the URL with xlsx@:

yarn add xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

监视存储库 或订阅 RSS 订阅 以在新版本发布时收到通知!

¥Watch the repo or subscribe to the RSS feed to be notified when new versions are released!

斯尼克虫子

Snyk 安全工具可能会报告涉及 "原型污染" 的错误:

¥Snyk security tooling may report errors involving "Prototype Pollution":

Prototype Pollution [Medium Severity][https://security.snyk.io/vuln/SNYK-JS-XLSX-5457926]

正如 斯尼克报告 中所述:

¥As noted in the Snyk report:

该问题已在 0.19.3 版本中解决

¥The issue is resolved in version 0.19.3

Snyk 错误地报告了漏洞。这是 Snyk 工具中的一个错误。

¥Snyk is falsely reporting vulnerabilities. It is a bug in the Snyk tooling.

在 Snyk 修复 bug 之前,官方推荐是 抑制警告

¥Until Snyk fixes the bugs, the official recommendation is to suppress the warning.

旧版端点

¥Legacy Endpoints

从技术上讲,较旧的版本可以在公共 npm 注册表中作为 xlsx 获得,但该注册表已过时。该注册表的最新版本是 0.18.5

¥Older releases are technically available on the public npm registry as xlsx, but the registry is out of date. The latest version on that registry is 0.18.5

这是一个已知的注册表错误

¥This is a known registry bug

SheetJS CDN https://cdn.sheetjs.com/ 是 SheetJS 模块的权威来源。

¥The SheetJS CDN https://cdn.sheetjs.com/ is the authoritative source for SheetJS modules.

对于现有项目,最简单的方法是卸载并重新安装:

¥For existing projects, the easiest approach is to uninstall and reinstall:

yarn remove xlsx
yarn add https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

xlsx 库是依赖的依赖时,package.json 中的 overrides 字段可以控制模块解析:

¥When the xlsx library is a dependency of a dependency, the overrides field in package.json can control module resolution:

package.json
{
"overrides": {
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
}
}

¥Vendoring

为了总体稳定性,强烈建议制作 SheetJS 模块 ("vendoring") 的本地副本。供应将项目与 SheetJS 基础设施解耦。

¥For general stability, making a local copy of SheetJS modules ("vendoring") is strongly recommended. Vendoring decouples projects from SheetJS infrastructure.

  1. 删除对名为 xlsx 的项目的任何现有依赖:

    ¥Remove any existing dependency on a project named xlsx:

yarn remove xlsx
  1. Download the tarball (xlsx-0.20.3.tgz) for the desired version. The current version is available at https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz

curl -o https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
  1. 在项目的根目录中创建一个 vendor 子文件夹:

    ¥Create a vendor subfolder at the root of your project:

mkdir -p vendor
  1. 将步骤 (1) 中的 tarball 移动到 vendor 文件夹:

    ¥Move the tarball from step (1) to the vendor folder:

mv xlsx-0.20.3.tgz vendor
  1. 如果项目使用版本控制系统进行管理,请将 tarball 添加到源存储库。Git VCS 支持 add 子命令:

    ¥If the project is managed with a version control system, add the tarball to the source repository. The Git VCS supports the add subcommand:

git add vendor/xlsx-0.20.3.tgz
  1. 使用包管理器安装 tarball:

    ¥Install the tarball using a package manager:

yarn add file:vendor/xlsx-0.20.3.tgz

Yarn 的较新版本可能会引发错误:

¥Newer releases of Yarn may throw an error:

Usage Error: The file:vendor/xlsx-0.20.3.tgz string didn't match the required format (package-name@range). Did you perhaps forget to explicitly reference the package name?

解决方法是将 xlsx@ 添加到 URI 前面:

¥The workaround is to prepend the URI with xlsx@:

yarn add xlsx@file:vendor/xlsx-0.20.3.tgz

该软件包将作为 xlsx 安装和访问。

¥The package will be installed and accessible as xlsx.

用法

¥Usage

该软件包支持 CommonJS require 和 ESM import 模块系统。

¥The package supports CommonJS require and ESM import module systems.

强烈建议在 NodeJS 中使用 CommonJS。

¥It is strongly recommended to use CommonJS in NodeJS.

CommonJS require

默认情况下,模块支持 require,它将自动添加对编码、流和文件系统访问的支持:

¥By default, the module supports require and it will automatically add support for encodings, streams and file system access:

var XLSX = require("xlsx");

ESM import

该软件包还附带 xlsx.mjs,这是一个与 ECMAScript 模块系统兼容的脚本。在 NodeJS 中使用 ESM 构建时,必须手动加载一些依赖。

¥The package also ships with xlsx.mjs, a script compatible with the ECMAScript module system. When using the ESM build in NodeJS, some dependencies must be loaded manually.

ECMAScript 模块限制

原始 ECMAScript 模块规范仅支持顶层导入​​:

¥The original ECMAScript module specification only supported top-level imports:

import { Readable } from 'stream';

如果模块不可用,脚本无法正常失败或忽略错误。这对库来说是一个难以克服的挑战。

¥If a module is unavailable, there is no way for scripts to gracefully fail or ignore the error. This presents an insurmountable challenge for libraries.

相比之下,SheetJS CommonJS 模块可以优雅地处理缺少的依赖,因为 require 故障是库可以捕获和处理的错误。

¥To contrast, the SheetJS CommonJS modules gracefully handle missing dependencies since require failures are errors that the library can catch and handle.


规范补丁为该问题添加了两种不同的解决方案:

¥Patches to the specification added two different solutions to the problem:

  • "动态导入" 将抛出可由库处理的错误。动态导入将污染不使用基于 Promise 的方法的 API。

    ¥"dynamic imports" will throw errors that can be handled by libraries. Dynamic imports will taint APIs that do not use Promise-based methods.

/* Readable will be undefined if stream cannot be imported */
const Readable = await (async() => {
try {
return (await import("stream"))?.Readable;
} catch(e) { /* silently ignore error */ }
})();
  • "导入映射" 控制模块解析,允许库用户手动分流不受支持的模块。

    ¥"import maps" control module resolution, allowing library users to manually shunt unsupported modules.

这些补丁是在浏览器采用 ESM 后发布的!许多浏览器和其他平台支持顶层导入​​,但不支持补丁。

¥These patches were released after browsers adopted ESM! A number of browsers and other platforms support top-level imports but do not support the patches.


对于 ESM 构建,有四个令人不快的选项:

¥For the ESM build, there were four unpalatable options:

A) 生成浏览器模块脚本、ViteJS 模块脚本、Deno 模块脚本、NodeJS 和 BunJS 模块脚本。

¥A) Generate a module script for browsers, a module script for ViteJS, a module script for Deno, and a module script for NodeJS and BunJS.

B) 删除所有可选功能,包括对非英语旧版文件的支持。

¥B) Remove all optional features, including support for non-English legacy files.

C) 添加所有可选功能,有效地使功能成为必需的。

¥C) Add all optional features, effectively making the features mandatory.

D) 引入可选依赖注入的特殊方法。

¥D) Introduce special methods for optional dependency injection.

SheetJS 团队选择了选项 (D)。NodeJS 原生模块仍会在 CommonJS 构建中自动加载,但 NodeJS ESM 脚本现在必须使用特殊方法加载并将依赖传递给库。

¥The SheetJS team chose option (D). NodeJS native modules are still automatically loaded in the CommonJS build, but NodeJS ESM scripts must now load and pass the dependencies to the library using special methods.


强烈建议在 NodeJS 脚本中使用 CommonJS!

¥It is strongly recommended to use CommonJS in NodeJS scripts!

文件系统操作

¥Filesystem Operations

set_fs 方法接受 fs 实例,用于使用 readFilewriteFile 读取和写入文件:

¥The set_fs method accepts a fs instance for reading and writing files using readFile and writeFile:

import * as XLSX from 'xlsx';

/* load 'fs' for readFile and writeFile support */
import * as fs from 'fs';
XLSX.set_fs(fs);

流操作

¥Stream Operations

set_readable 方法接受 stream.Readable 实例以用于包括 XLSX.stream.to_csv 在内的流方法:

¥The set_readable method accepts a stream.Readable instance for use in stream methods including XLSX.stream.to_csv:

import * as XLSX from 'xlsx';

/* load 'stream' for stream support */
import { Readable } from 'stream';
XLSX.stream.set_readable(Readable);

编码支持

¥Encoding Support

set_cptable 方法接受 SheetJS 代码页库的实例以用于旧文件格式处理。cpexcel.full.mjs 脚本必须手动加载。xlsx/dist/cpexcel.full.mjs 可以导入:

¥The set_cptable method accepts an instance of the SheetJS codepage library for use in legacy file format processing. The cpexcel.full.mjs script must be manually loaded. xlsx/dist/cpexcel.full.mjs can be imported:

import * as XLSX from 'xlsx';

/* load the codepage support library for extended support with older formats */
import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs';
XLSX.set_cptable(cpexcel);

NextJS

fs 无法从 NextJS 页面的顶层导入。这是行不通的:

¥fs cannot be imported from the top level in NextJS pages. This will not work:

/* it is safe to import the library from the top level */
import { readFile, utils, set_fs } from 'xlsx';
/* it is not safe to import 'fs' from the top level ! */
import * as fs from 'fs'; // this import will fail
set_fs(fs);

这是 NextJS 的一个设计缺陷!

¥This is a design flaw in NextJS!

对于服务器端文件处理,fs 应该在生命周期函数中通过动态导入进行加载:

¥For server-side file processing, fs should be loaded with a dynamic import within a lifecycle function:

index.js
/* it is safe to import the library from the top level */
import { readFile, utils, set_fs } from 'xlsx';
import { join } from 'path';
import { cwd } from 'process';

export async function getServerSideProps() {
set_fs(await import("fs")); // dynamically import 'fs' in `getServerSideProps`
const wb = readFile(join(cwd(), "public", "sheetjs.xlsx"));
// ...
}

NextJS 演示 包含完整的示例。

¥The NextJS demo includes complete examples.