前端导出excel
AprilTong 7/26/2021 Javascript
# xlsx 介绍
由 SheetJS 出品的 js-xlsx 是一款非常方便的只需要纯 JS 即可读取和导出 excel 的工具库,功能强大,支持格式众多,支持 xls、xlsx、ods(一种 OpenOffice 专有表格文件格式)等十几种格式。也可以设置样式等。
# 导出 excel 实现
- 下载 xlsx 然后引入
使用 npm 进行下载
npm install xlsx
1
import XLSX from 'xlsx'
1
- 导出文件
/**
*
* @param sheetData 数组表格数据
* @param fileName 文件名
*/
function exportFile(sheetData, fileName) {
// 将由对象组成的数组转化成sheet
const sheet = XLSX.utils.json_to_sheet(sheetData)
// 百分数和数字更改为数字类型
Object.keys(sheet).forEach((key) => {
if (sheet[key].v) {
const val = sheet[key].v
if (!isNaN(val)) {
sheet[key].t = 'n'
}
if (val.lastIndexOf('%') === val.length - 1) {
sheet[key].t = 'n'
sheet[key].z = '0.00%'
sheet[key].v = Number(val.substring(0, val.length - 1)) / 100
}
}
})
// 创建虚拟的workbook
const wb = XLSX.utils.book_new()
// 把sheet添加到workbook中
XLSX.utils.book_append_sheet(wb, sheet, fileName)
const workbookBlob = workbook2blob(wb)
openDownload(workbookBlob, `${fileName}.xls`)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
- 将 blob 对象创建 blobUrl,通过 a 标签和 createObjectURL 实现下载功能实现下载
function openDownload(blob, fileName) {
if (typeof blob === 'object' && blob instanceof Blob) {
blob = URL.createObjectURL(blob) // 创建blob地址
}
const aLink = document.createElement('a')
aLink.href = blob
// HTML5新增的属性,指定保存文件名,可以不要后缀,注意,有时候 file:///模式下不会生效
aLink.download = fileName || ''
let event
if (window.MouseEvent) event = new MouseEvent('click')
// 移动端
else {
event = document.createEvent('MouseEvents')
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
}
aLink.dispatchEvent(event)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 将 workbook 装化成 blob 对象
function workbook2blob(workbook) {
// 生成excel的配置项
const wopts = {
// 要生成的文件类型
bookType: 'xlsx',
// // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
bookSST: false,
type: 'binary',
}
const wbout = XLSX.write(workbook, wopts)
// 将字符串转ArrayBuffer
function s2ab(s: string) {
const buf = new ArrayBuffer(s.length)
const view = new Uint8Array(buf)
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
return buf
}
const blob = new Blob([s2ab(wbout)], {
type: 'application/octet-stream',
})
return blob
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- 如何使用
let sheetData = [
{
name: 'april',
age: '24',
},
{
name: 'bran',
age: '26',
},
]
exportFile(sheetData, '人员统计')
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 遇到的问题
数字和百分数导出后,在 excel 中无法选中进行计算,双击单元格之后又可以了。 查看文档发现可以设置单元格对象的类型: 解决:
- 对于可以转为数字的设置其类型为 n(number)
- 对于百分数,对其单元格这样设置
sheet[key].t = 'n'
sheet[key].z = '0.00%'
sheet[key].v = Number(val.substring(0, val.length - 1)) / 100
1
2
3
2
3
# 其他导出
- 调接口后端返回文件流实现