使用 Webpack 打包工作表
Webpack 是一个模块打包器。
¥Webpack is a module bundler.
SheetJS 是一个用于从电子表格读取和写入数据的 JavaScript 库。
¥SheetJS is a JavaScript library for reading and writing data from spreadsheets.
该演示使用 Webpack 和 SheetJS 导出数据。我们将探讨如何使用 Webpack 将 SheetJS 打包到网站中,以及如何将数据导出到电子表格。
¥This demo uses Webpack and SheetJS to export data. We'll explore how to bundle SheetJS in a site using Webpack and how to export data to spreadsheets.
内容演示的 Webpack 部分 涵盖资源加载器。它们非常适合静态站点在构建时从工作表中提取数据。
¥The Webpack section of the Content demo covers asset loaders. They are ideal for static sites pulling data from sheets at build time.
该演示重点介绍与 Webpack 打包器的集成细节。
¥This demo focuses on integration details with the Webpack bundler.
这些演示遵循 "导出教程",其中更详细地介绍了 SheetJS 库的用法。
¥The demos follow the "Export Tutorial", which covers SheetJS library usage in more detail.
本 demo 在以下环境下进行了测试:
¥This demo was tested in the following environments:
版本 | 日期 | 所需的解决方法 |
---|---|---|
2.7.0 | 2024-03-16 | 导入 xlsx/dist/xlsx.full.min.js |
3.12.0 | 2024-03-16 | 导入 xlsx/dist/xlsx.full.min.js |
4.47.0 | 2024-03-16 | 降级 NodeJS(测试 v16.20.2) |
5.90.3 | 2024-03-16 |
集成详情
¥Integration Details
"构架" 章节 涵盖了 Yarn 和其他包管理器的安装。
¥The "Frameworks" section covers installation with Yarn and other package managers.
在 Webpack 5 项目中安装 SheetJS 模块后,import
语句和 require
表达式可以加载库的相关部分。
¥After installing the SheetJS module in a Webpack 5 project, import
statements
and require
expressions can load relevant parts of the library.
ECMAScript 模块构建没有 require
或 import
语句,并且不使用 process
或 Webpack 可以解释为 NodeJS 功能的任何变量。添加了各种 package.json
字段,以适应从 2.x
系列开始的各种 Webpack 版本。
¥The ECMAScript Module build has no require
or import
statements and does
not use process
or any variable that Webpack could interpret as a NodeJS
feature. Various package.json
fields have been added to appease various
Webpack versions starting from the 2.x
series.
导入数据的项目将使用 read
[^1] 等方法解析工作簿,使用 sheet_to_json
[^2] 从文件生成可用数据。由于 sheet_to_json
是 utils
对象的一部分,因此所需的导入为:
¥Projects that import data will use methods such as read
[^1] to parse workbooks
and sheet_to_json
[^2] to generate usable data from files. As sheet_to_json
is part of the utils
object, the required import is:
import { read, utils } from 'xlsx';
导出数据的项目会使用 json_to_sheet
[^3] 等方法生成工作表,使用 writeFile
[^4] 导出文件。由于 json_to_sheet
是 utils
对象的一部分,因此所需的导入为:
¥Projects that export data will use methods such as json_to_sheet
[^3] to
generate worksheets and writeFile
[^4] to export files. As json_to_sheet
is
part of the utils
object, the required import is:
import { utils, writeFile } from 'xlsx';
writeFileXLSX
函数是 writeFile
的小型版本,专门支持生成 XLSX 电子表格。当应用仅允许 XLSX 导出时,writeFileXLSX
将减小最终页面大小。
¥The writeFileXLSX
function is a small version of writeFile
that exclusively
supports generating XLSX spreadsheets. When the application only allows XLSX
exports, writeFileXLSX
will reduce the final page size.
CommonJS 和 ESM
¥CommonJS and ESM
Webpack 将 CommonJS 构建打包在旧版本的库中。版本 0.18.1
更改了 NodeJS 模块包,以便 Webpack 使用 ESM 构建。
¥Webpack bundled the CommonJS build in older versions of the library. Version
0.18.1
changed the NodeJS module package so that Webpack uses the ESM build.
CommonJS 版本包括用于 XLS 处理的代码页支持库。
¥The CommonJS build includes the codepage support library for XLS processing.
ESM 版本不包括代码页支持库。如安装说明中所述,应显式导入代码页依赖:
¥The ESM build does not include the codepage support library. As described in the installation instructions, the codepage dependency should be imported explicitly:
import * as XLSX from 'xlsx';
import * as cptable from 'xlsx/dist/cpexcel.full.mjs';
set_cptable(cptable);
旧版 Webpack
¥Legacy Webpack
一些较旧的 webpack 项目会在浏览器中抛出错误:
¥Some older webpack projects will throw an error in the browser:
require is not defined (xlsx.mjs)
这是 Webpack 中的一个错误,影响了使用 create-react-app
构建的项目。如果升级 Webpack 不可行,请显式导入独立脚本:
¥This was a bug in Webpack and affected projects built with create-react-app
.
If upgrading Webpack is not feasible, explicitly import the standalone script:
import * as XLSX from 'xlsx/dist/xlsx.full.min.js';
完整示例
¥Complete Example
-
初始化一个新项目:
¥Initialize a new project:
mkdir sheetjs-webpack
cd sheetjs-webpack
npm init -y
-
使用包管理器安装 tarball:
¥Install the tarball using a package manager:
- npm
- pnpm
- Yarn
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
pnpm install --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
yarn add https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
-
将以下内容保存到
index.js
:¥Save the following to
index.js
:
import { utils, version, writeFileXLSX } from 'xlsx';
document.getElementById("xport").addEventListener("click", function() {
/* fetch JSON data and parse */
var url = "https://xlsx.nodejs.cn/executive.json";
fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) {
/* filter for the Presidents */
var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); });
/* sort by first presidential term */
prez.forEach(function(row) {
row.start = row.terms.find(function(term) {
return term.type === "prez";
}).start
});
prez.sort(function(l,r) { return l.start.localeCompare(r.start); });
/* flatten objects */
var rows = prez.map(function(row) { return {
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}; });
/* generate worksheet and workbook */
var worksheet = utils.json_to_sheet(rows);
var workbook = utils.book_new();
utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
writeFileXLSX(workbook, "Presidents.xlsx");
});
});
Webpack 2.x 附带的压缩器不处理 async
函数或 ES6 箭头函数。
¥The minifier that ships with Webpack 2.x does not handle async
functions or
ES6 arrow functions.
为了演示与旧版本 Webpack 的兼容性,index.js
脚本使用普通函数和传统的 Promise 链。
¥To demonstrate compatibility with older versions of Webpack, the index.js
script uses normal functions and traditional Promise chains.
-
创建一个写入
index.min.js
的小webpack.config.js
脚本:¥Create a small
webpack.config.js
script that writes toindex.min.js
:
module.exports = {
/* entry point index.js */
entry: './index.js',
/* write to index.min.js */
output: { path:__dirname, filename: './index.min.js' }
}
-
为生产而构建。该命令取决于 webpack 的版本:
¥Build for production. The command depends on the version of webpack:
- 2.x and 3.x
- 4.x, 5.x and beyond
在 Webpack 2.x 和 3.x 中,导入语句必须使用独立脚本。将 index.js
中的 import 语句替换为以下内容:
¥In Webpack 2.x and 3.x, the import statement must use the standalone script.
Replace the import statement in index.js
with the following:
import { utils, version, writeFileXLSX } from 'xlsx/dist/xlsx.full.min.js';
打包前必须更改此行。
¥This line must be changed before bundling.
Webpack 2.x
npx webpack@2.x -p
Webpack 3.x
npx webpack@3.x -p
webpack 工具并不是为版本之间的切换而设计的。4.0 以上的特定版本可以通过本地安装 webpack 和 CLI 工具来固定。
¥The webpack tooling is not designed for switching between versions. A specific version above 4.0 can be pinned by locally installing webpack and the CLI tool.
Webpack 4.x
Webpack 4 与 Node 18+ 不兼容。它将引发以下错误:
¥Webpack 4 is incompatible with Node 18+. It will elicit the following error:
Error: error:0308010C:digital envelope routines::unsupported
上次测试此演示时,NodeJS 已本地降级至 16.20.2
¥When this demo was last tested, NodeJS was locally downgraded to 16.20.2
npm i --save webpack@4.x webpack-cli@4.x
npx webpack --mode=production
Webpack 5.x
npm i --save webpack@5.x webpack-cli@5.x
npx webpack --mode=production
Webpack 最新
¥Webpack latest
npm i --save webpack webpack-cli
npx webpack --mode=production
-
创建一个加载脚本的小型 HTML 页面。保存到
index.html
:¥Create a small HTML page that loads the script. Save to
index.html
:
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<h1>SheetJS Presidents Demo</h1>
<button id="xport">Click here to export</button>
<script src="./index.min.js"></script>
</body>
</html>
-
启动本地 HTTP 服务器:
¥Start a local HTTP server:
npx http-server .
-
在 Web 浏览器中加载显示的 URL(通常为
http://localhost:8080/
)。¥Load the displayed URL (typically
http://localhost:8080/
) in a web browser.
点击 "点击此处导出" 生成文件。
¥Click on "Click here to export" to generate a file.
杂项
¥Miscellany
[^1]: 见 read
于 "读取文件"
[^2]: 见 sheet_to_json
于 "实用工具"
¥See sheet_to_json
in "Utilities"
[^3]: 见 json_to_sheet
于 "实用工具"
¥See json_to_sheet
in "Utilities"
[^4]: 见 writeFile
于 "写入文件"