项目要用到前端excel导出功能,找到js-xlsx希望啃下
安装
npm install xlsx --save
npm install file-saver --save
npm install blob.js --save
引用
import XLSX from 'xlsx';
import FileSaver from 'file-saver';
import 'blob.js'
后面2个包用来实现在本地机器上的文件下载,知道它们的安装和用法就行,不去深究。
const s2ab = s => {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
};
FileSaver.saveAs(new Blob([s2ab(workbook)], {
type: 'application/octet-stream'
}), fileName + '.xlsx')
使用库之前先理解一下它的概念
workbook [excel文档]
首先是workbook
,可以把它看作是一个excel文档。
我们要用xlsx导出excel,就是要按规范创建workbook
一个简单的workbook对象是这样的
const workbook = {
SheetNames: [], //工作表名数组
Sheets: {} //工作表对象 键名对应SheetNames的key
}
sheet [工作表]
从workbook
对象下面延伸出来的是sheet
对象,很容易理解,它对应这个excel文档下面的工作表
一个workbook
可以有多个sheet
,就像下面这个对象这样,等于是有三个工作表的excel文档
sheet
的常用配置项,我在代码中注释出来
const workbook = {
SheetNames: [ //工作表名数组
'Sheet1', 'Sheet2', 'Sheet2',
],
Sheets: { //工作表对象
Sheet1: { //工作表1
'!ref': 'A1:C2', //工作表的范围 如 必须 否则不显示
'!margins': [ //工作表单元格合并配置项 可选
{
s: { //s start 开始
c: 1,//cols 开始列
r: 0 //rows 开始行
},
e: {//e end 结束
c: 4,//cols 结束列
r: 0 //rows 结束行
}
}
],
'!cols': [ //工作表列宽配置项 可选
{
/* visibility */
hidden? : boolean, // if true, the column is hidden
/* column width is specified in one of the following ways: */
wpx? : number, // width in screen pixels
width? : number, // width in Excel's "Max Digit Width", width*256 is integral
wch? : number, // width in characters
/* other fields for preserving features from files */
MDW? : number, // Excel's "Max Digit Width" unit, always integral
}
],
'!rows': [ //工作表列高配置项 可选
{
/* visibility */
hidden? : boolean, // if true, the row is hidden
/* row height is specified in one of the following ways: */
hpx? : number, // height in screen pixels
hpt? : number, // height in points
level? : number, // 0-indexed outline / group level
}
],
},
Sheet2: {}, //工作表2
Sheet3: {} //工作表3
}
}
cell [单元格]
从sheet
对象下面延伸出来的是cell
对象,对应的是工作表下的单元格,cell
对象键名是A1,B1这样与excel一致的键名
const workbook = {
FileName: 'export.xlsx',
SheetNames: ['Sheet1'],
Sheets: {
Sheet1:{
'!ref': 'A1:B2',
A1:{},
A2:{},
B1:{},
B2:{}
}
}
}
js-xlsx提供了一个方法XLSX.utils.encode_cell
来转换键名
XLSX.utils.encode_cell({
c: 0, //cols 列
r: 0 //rows 行
};
知道相应的行列值就能方便的转换成键名了,需要注意的是行列是从0开始不是从1开始
XLSX.utils.encode_cell({c: 0, r: 0});//A1
XLSX.utils.encode_cell({c: 0, r: 1});//A2
XLSX.utils.encode_cell({c: 1, r: 0});//B1
XLSX.utils.encode_cell({c: 1, r: 1});//B2
XLSX.utils.encode_cell({c: 100, r: 100});//CW101
cell单元格对象的配置项
键名 | 作用 |
---|---|
v | 初始值 (请参见数据类型t 部分) |
w | 格式化文本 (如果适用) |
t | 单元格数据类型: b Boolean, n Number, e error, s String, d Date |
f | 单元格编码为A1样式的字符串(如果适用) |
F | 如果公式为数组公式,则包含数组的范围(如适用) |
r | 富文本编码(如适用) |
h | HTML 富文本呈现(如适用) |
c | 单元格注释 |
z | 与单元格关联的数字格式字符串(如果请求) |
l | 单元格超链接对象(.Target holds link, .Tooltip is tooltip) |
s | 单元格的样式/主题(如果适用) |
大概搞懂了workbook
配置,先来创建一个简单的workbook
看看是否能正常导出,这里要用到xlsx的write
函数
XLSX.write(workbook, options)生成excel数据
第一个参数传入写好的workbook
,第二个参数是配置项
write options 配置项
键名 | 默认值 | 描述 |
---|---|---|
type | 输出数据编码(见下表Output Type) | |
cellDates | false | 存储日期为d类型(默认为n) |
bookSST | false | 生成共享字符串表 |
bookType | "xlsx" | 文档格式类型 |
sheet | "" | 单页格式的工作表名称 |
compression | false | 对基于ZIP的格式使用ZIP压缩 |
Props | 重写工作簿时重写工作簿属性 | |
themeXLSX | Override theme XML when writing XLSX/XLSB/XLSM |
Output Type
type | output |
---|---|
"base64" | string: Base64 encoding of the file |
"binary" | string: binary string (byte n is data.charCodeAt(n)) |
"string" | string: JS string (characters interpreted as UTF8) |
"buffer" | nodejs Buffer |
"file" | string: path of file that will be created (nodejs only) |
感觉上面学习的内容已经足够导出一个简单的excel了,我先来试下
const workbook = {
SheetNames: ['Sheet1'],
Sheets: {
Sheet1: {
'!ref': 'A1:C2',
A1: {v: '标题1', t: 's'},
B1: {v: '标题2', t: 's'},
A2: {v: '第2行第1列', t: 's'},
B2: {v: '第2行第2列', t: 's'},
}
}
};
const workbookOut = XLSX.write(workbook, {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
});
FileSaver.saveAs(new Blob([s2ab(workbookOut)], {
type: 'application/octet-stream'
}), 'export.xlsx')
运行 顺利生成export.xlsx