Complete Example完整示例
SheetJS presents a simple JS interface that works with "Array of Arrays" and "Array of JS Objects". SheetJS提供了一个简单的JS接口,可与“数组数组”和“JS对象数组”一起使用。The API functions are building blocks that should be combined with other JS APIs to solve problems.API函数是构建块,应该与其他JSAPI结合来解决问题。
The discussion focuses on the problem solving mindset. 讨论的重点是解决问题的心态。API details are covered in other parts of the documentation.API详细信息包含在文档的其他部分中。
The goal of this example is to generate a XLSX workbook of US President names and birthdays. 本例的目标是生成一个包含美国总统姓名和生日的XLSX工作簿。Click here点击此处 to jump to the live demo跳转到现场演示
Acquire Data
Raw Data
The raw data is available in JSON form. 原始数据以JSON形式提供。For convenience, it has been mirrored here为方便起见,此处已对其进行了镜像。
The data result is an Array of objects. 数据结果是一个对象数组。 This is the data for John Adams:以下是John Adams的数据:
{
"id": { /* (data omitted) */ },
"name": {
"first": "John", // <-- first name
"last": "Adams" // <-- last name
},
"bio": {
"birthday": "1735-10-19", // <-- birthday
"gender": "M"
},
"terms": [
{ "type": "viceprez", /* (other fields omitted) */ },
{ "type": "viceprez", /* (other fields omitted) */ },
{ "type": "prez", /* (other fields omitted) */ }
]
}
Filtering for Presidents筛选总统
The dataset includes Aaron Burr, a Vice President who was never President!数据集包括亚伦·伯尔,一位从未当过总统的副总统!
Array#filter
creates a new array with the desired rows. 使用所需行创建新数组。A President served at least one term with 总统至少任期一届,type
set to "prez"
. type
设置为"prez"
。To test if a particular row has at least one 为了测试特定行是否至少有一个"prez"
term, Array#some
is another native JS function. "prez"
项,Array#some
是另一个本机JS函数。The complete filter would be:完整的筛选器将是:
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
Reshaping the Array重塑数组形状
For this example, the name will be the first name combined with the last name (在本例中,名称将是名与姓(row.name.first + " " + row.name.last
) and the birthday will be the subfield row.bio.birthday
. row.name.first + " " + row.name.last
)的组合,生日将是子字段row.bio.birthday
。Using 使用Array#map
, the dataset can be massaged in one call:Array#map
,可以在一次调用中对数据集进行按摩:
constrows=prez.map(row => ({
name:row.name.first + " " +row.name.last,
birthday:row.bio.birthday
}));
The result is an array of "simple" objects with no nesting:结果是一个没有嵌套的“简单”对象数组:
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
Create a Workbook创建工作簿
With the cleaned dataset, 使用清理后的数据集,XLSX.utils.json_to_sheet
generates a worksheet:XLSX.utils.json_to_sheet
生成一个工作表:
constworksheet= XLSX.utils.json_to_sheet(rows);
XLSX.utils.book_new
creates a new workbook and XLSX.utils.book_append_sheet
appends a worksheet to the workbook. XLSX.utils.book_new
创建新工作簿,XLSX.utils.book_append_sheet
将工作表附加到工作簿。The new worksheet will be called "Dates":新工作表将被称为“日期”:
constworkbook= XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook,worksheet, "Dates");
Clean up Workbook清理工作簿
The data is in the workbook and can be exported.数据位于工作簿中,可以导出。
There are multiple opportunities for improvement: the headers can be renamed and the column widths can be adjusted. 有多种改进机会:可以重命名标题,调整列宽。SheetJS Pro offers additional styling options like cell styling and frozen rows.提供其他样式选项,如单元格样式和冻结行。
Changing Header Names更改标题名称 (click to show)
By default, 默认情况下,json_to_sheet
creates a worksheet with a header row. json_to_sheet
创建一个带有标题行的工作表。In this case, the headers come from the JS object keys: "name" and "birthday".在本例中,标题来自JS对象键:“name”和“birthday”。
The headers are in cells A1 and B1. 标题位于单元格A1和B1中。XLSX.utils.sheet_add_aoa
can write text values to the existing worksheet starting at cell A1:可以从单元格A1开始将文本值写入现有工作表:
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
Changing Column Widths更改列宽 (click to show)
Some of the names are longer than the default column width. 有些名称比默认列宽长。Column widths are set by setting the 通过设置"!cols"
worksheet property."!cols"
工作表属性来设置列宽。
The following line sets the width of column A to approximately 10 characters:以下行将A列的宽度设置为大约10个字符:
worksheet["!cols"] = [ { wch: 10 } ]; // set column A width to 10 characters
One 一个Array#reduce
call over rows
can calculate the maximum width:Array#reduce
调用遍历rows
可以计算最大宽度:
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
worksheet["!cols"] = [ { wch: max_width } ];
Export a File导出文件
XLSX.writeFile
creates a spreadsheet file and tries to write it to the system. 创建电子表格文件并尝试将其写入系统。In the browser, it will try to prompt the user to download the file. 在浏览器中,它将尝试提示用户下载文件。In NodeJS, it will write to the local directory.在Node.js中,它将写入本地目录。
XLSX.writeFile(workbook, "Presidents.xlsx");
Live Demo
Run the Demo Locally在本地运行演示
- Browser
- NodeJS
- Deno
Save the following script to 将以下脚本保存到snippet.html
and open the page. snippet.html
并打开页面。The page must be hosted (no 页面必须托管(不能用file:///
access).file:///
访问)。
https://sheetjs.com/pres.html is a hosted version of the page.是页面的托管版本。
<body>
<script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
<script>
(async() => {
/* fetch JSON data and parse */
const url = "https://sheetjs.com/executive.json";
const raw_data = await (await fetch(url)).json();
/* filter for the Presidents */
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
/* flatten objects */
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFile(workbook, "Presidents.xlsx");
})();
</script>
<body>
Install the dependencies:安装依赖项:
$npmi --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
Save the following script to 将以下脚本保存到snippet.js
and run node snippet.js
:snippet.js
并运行node snippet.js
:
const XLSX = require("xlsx");
(async() => {
/* fetch JSON data and parse */
const url = "https://sheetjs.com/executive.json";
const raw_data = await (await fetch(url)).json();
/* filter for the Presidents */
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
/* flatten objects */
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFile(workbook, "Presidents.xlsx");
})();
Native Node.js 18中添加了原生fetch
support was added in NodeJS 18. fetch
支持。For older versions of NodeJS, the script will throw an error 对于旧版本的Node.js,脚本将抛出一个错误,即fetch is not defined
. fetch is not defined
。A third-party library like 像axios
presents a similar API for fetching data:axios
这样的第三方库提供了一个类似的API来获取数据:
Example using axios使用axios的示例 (click to show)
Install the dependencies:安装依赖项:
$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
The differences in the script are highlighted below.脚本中的差异如下所示。
const XLSX = require("xlsx");
const axios = require("axios");
(async() => {
/* fetch JSON data and parse */
const url = "https://sheetjs.com/executive.json";
const raw_data = (await axios(url, {responseType: "json"})).data;
/* filter for the Presidents */
const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
/* flatten objects */
const rows = prez.map(row => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFile(workbook, "Presidents.xlsx");
})();
Save the following script to 将以下脚本保存到snippet.ts
and run with deno run --allow-net --allow-write snippet.ts
:snippet.ts
,并使用deno run --allow-net --allow-write snippet.ts
运行:
// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
/* fetch JSON data and parse */
const url = "https://sheetjs.com/executive.json";
const raw_data = await (await fetch(url)).json();
/* filter for the Presidents */
const prez = raw_data.filter((row: any) => row.terms.some((term: any) => term.type === "prez"));
/* flatten objects */
const rows = prez.map((row: any) => ({
name: row.name.first + " " + row.name.last,
birthday: row.bio.birthday
}));
/* generate worksheet and workbook */
const worksheet = XLSX.utils.json_to_sheet(rows);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
/* fix headers */
XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
/* calculate column width */
const max_width = rows.reduce((w: number, r: any) => Math.max(w, r.name.length), 10);
worksheet["!cols"] = [ { wch: max_width } ];
/* create an XLSX file and try to save to Presidents.xlsx */
XLSX.writeFile(workbook, "Presidents.xlsx");