前端导出excel

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
  • 将 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
  • 将 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
  • 如何使用
let sheetData = [
    {
        name: 'april',
        age: '24',
    },
    {
        name: 'bran',
        age: '26',
    },
]
exportFile(sheetData, '人员统计')
1
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

# 其他导出

  • 调接口后端返回文件流实现

之前的一篇文章 (opens new window)

# 参考文章

上次更新: 7/27/2021, 11:01:18 AM