Vue中使用xlsx导出excel表格和把导入的excel表处理成json数据

安装

1
npm install xlsx -S

一、通过dom元素导出excel表格

创建公共方法

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
30
31
32
import XLSX from 'xlsx'

/**
* 该方法用于通过dom导出表格
* @param el dom元素
* @param excelName 表格名称
* @returns {any}
*/
export function exportExcel(el, excelName) {
/* 从表生成工作簿对象 */
const wb = XLSX.utils.table_to_book(el);
/* 获取二进制字符串作为输出 */
const wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: true,
type: 'array'
});
try {
FileSaver.saveAs(
// Blob 对象表示一个不可变、原始数据的类文件对象。
// Blob 表示的不一定是JavaScript原生格式的数据。
// File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
// 返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
new Blob([wbout], { type: 'application/octet-stream' }),
// 设置导出文件名称
`${excelName}.xlsx`
);
} catch (e) {
if (typeof console !== 'undefined') console.log(e, wbout);
}
return wbout;
}

二、把从后台获取到的数据后直接导出为excel表格

创建公共方法

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import XLSX from 'xlsx'

function autoWidthFunc(ws, data) {
const colWidth = data.map(row => row.map(val => {
if (val == null) {
return {
wch: 10
}
} else if (val.toString().charCodeAt(0) > 255) {
return {
wch: val.toString().length * 2
}
}
return {
wch: val.toString().length
}
}))
const result = colWidth[0]
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j].wch < colWidth[i][j].wch) {
result[j].wch = colWidth[i][j].wch
}
}
}
// 设置表格样式,!cols为列宽
ws['!cols'] = result
}

function jsonToArray(key, jsonData) {
return jsonData.map(v => key.map(j => {
return v[j]
}))
}

/**
* 创建并导出excel
* @param key 数据中对象的键名 ['id', 'title', 'desc']
* @param data 导出的数据源 [{id:'1',title:'',desc:''}]
* @param title 表头 ['id','标题','描述']
* @param fileName 文件名
* @param autoWidth 是否自适应文件宽度
* @param columnsWidth 自定义宽度(选填) 当autoWidth为false或者undefined时使用
*/
export function exportArrayToExcel({
key,
data,
title,
fileName,
autoWidth,
columnsWidth
}) {
// 新建一个工作簿
const wb = XLSX.utils.book_new()
const arr = jsonToArray(key, data)
arr.unshift(title)
// 制作工作表 将一组 JS 数据数组转换为工作表
const ws = XLSX.utils.aoa_to_sheet(arr)
if (autoWidth) {
// 处理表格列宽
autoWidthFunc(ws, arr)
} else if (columnsWidth) {
ws['!cols'] = columnsWidth
}
/* 将工作表添加到工作簿 */
XLSX.utils.book_append_sheet(wb, ws, fileName)
/* 输出工作表, 由文件名决定的输出格式 */
XLSX.writeFile(wb, `${fileName}.xlsx`)
}

vue页面中使用

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
import {
exportArrayToExcel
} from "@/assets/js/exportExcel"

export default {
data() {
return {
dataList: [] //请求的数据放到这里
}
},
methods: {
// 页面上有个按钮 点击调用本方法,不赘述
exportExcel() {
const params = {
// dataList中的字段 title,key 需要一一对应
title: ['订单号', '订单来源', '车牌号'],
key: ['app_id', 'app_source', 'cars'],
data: this.dataList, // 数据源
autoWidth: true,
// 时间戳函数自己定义formatDate
filename: '清单' + formatDate(new Date(), 'yyyyMMddhhmmss')
}
exportArrayToExcel(params)
}
}
}

三、把导入的excel表处理成json数据

创建公共方法

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import XLSX from 'xlsx'

/**
* 把excel中的数据转换为json数据
* @param file 文件
* @param keys 对应的键值 从左到右依次对应
* @param startIndex 数据开始的位置,默认为1
*/
export function exportExcelToJson({
file,
keys,
startIndex = 1
}) {
const reader = new FileReader()
reader.onload = (event) => {
console.log(event)
const data = event.target.result
const workbook = XLSX.read(data, {
type: 'binary'
})
const resultArray = []
workbook.SheetNames.forEach((sheetName) => {
const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {
header: 1
})
const mainData = data.slice(startIndex)
if (mainData.length > 0) {
if (!keys) {
keys = data[0]
}
mainData.forEach(item => {
const rowData = {}
keys.forEach((key, keyIndex) => {
rowData[key] = item[keyIndex] || ''
})
resultArray.push(rowData)
})
}
})
console.log('resultArray', resultArray)
}
reader.readAsBinaryString(file)
}

vue中调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<input type="file" onclick="this.value=null" ref="uploadFile"/>
</div>
</template>
import { exportExcelToJson } from "@/assets/js/exportExcel"

export default {
methods: {
// 页面上有个按钮 点击调用本方法,不赘述
excelToJson () {
const that = this
const file = that.$refs.uploadFile.files[0]
const keys = ['app_id', 'app_source', 'cars']
exportExcelToJson({
file,
keys,
startIndex:1
})
}
}
}