解析Excel

  1. 1. 准备工作
    1. 1.1. 安装npm包 xlsx
    2. 1.2. 创建页面用于编写例子,需要上传组件、导出按钮、表格组件(均为ant-design框架的组件)
    3. 1.3. 导入包和准备数据
  2. 2. 导入数据
  3. 3. 导出数据

使用js-xlsx解析Excel文件进行导入导出操作

准备工作

安装npmxlsx

1
pnpm install xlsx

创建页面用于编写例子,需要上传组件、导出按钮、表格组件(均为ant-design框架的组件)

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div style="margin: 60px;">
<a-upload v-model:file-list="rt.fileList" name="file" action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
@change="uploadFile">
<a-button>
<upload-outlined></upload-outlined>导入
</a-button>
</a-upload>
<a-button type="primary" @click="onExport">导出</a-button>
<a-table id="table" :columns="columns" :dataSource="rt.data" bordered :pagination="false"></a-table>
</div>
</template>

导入包和准备数据

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
70
71
72
73
74
75
76
77
78
import { reactive } from 'vue';
import type { UploadChangeParam } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import * as XLSX from 'xlsx';
interface Idata {
candidate: string,
name: string,
chinese: number,
math: number,
english: number,
computer: number,
totalScore: number,
provinceRank: number,
classRank: number
}
interface SourceDate {
"考生号": string,
"姓名": string,
"数学": number,
"英语": number,
"计算机": number,
"语文": number,
"总分": number,
"全省排名": number,
"全班排名": number
}
const rt = reactive({
data: [] as Idata[],
fileList: [] as UploadChangeParam[]
})

const columns = [
{
title: '考生号',
dataIndex: 'candidate',
key: 'candidate',
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '语文',
dataIndex: 'chinese',
key: 'chinese',
},
{
title: '数学',
key: 'math',
dataIndex: 'math',
},
{
title: '英语',
key: 'english',
dataIndex: 'english',
},
{
title: '计算机',
dataIndex: 'computer',
key: 'computer',
},
{
title: '总分',
dataIndex: 'totalScore',
key: 'totalScore',
},
{
title: '全省排名',
dataIndex: 'provinceRank',
key: 'provinceRank',
},
{
title: '全班排名',
dataIndex: 'classRank',
key: 'classRank',
}
]

导入数据

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
// 此事件绑定在上传组件上,组件change时触发
// info:上传后的文件对象
const uploadFile = (info: UploadChangeParam) => {
// 未配置上传接口,上传状态必定error,因此让函数在error状态下触发
if (info.file.status === 'error') {
const reader = new FileReader();
if (info.file.originFileObj) {
reader.readAsArrayBuffer(info.file.originFileObj);
reader.onload = function () {
// result则是我们在excel表中获取的数据
const buffer = reader.result as ArrayBuffer;
// 通过XLSX读取出来得到了一个 workdata 对象
const wb = XLSX.read(buffer, { type: 'binary' });
// 将工作表中的数据转换为json对象
const outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]) as SourceDate[];
// 通过遍历将数据push到Table组件绑定的 dataSource 中
outdata.forEach(item => {
const temp = {
candidate: item["考生号"],
name: item["姓名"],
chinese: item["语文"],
math: item["数学"],
english: item["英语"],
computer: item["计算机"],
totalScore: item["总分"],
provinceRank: item["全省排名"],
classRank: item["全班排名"]
}
rt.data.push(temp)
})
}
}
}
}

导出数据

1
2
3
4
5
6
7
8
9
10
11
const onExport = () => {
// DOM表格节点导出为excel
const wb1 = XLSX.utils.table_to_book(document.getElementById('table'));
XLSX.writeFile(wb1, `报表导出.xlsx`);

// json数组对象导出为excel
const wb2 = XLSX.utils.book_new();
const ws2 = XLSX.utils.json_to_sheet(rt.data);
XLSX.utils.book_append_sheet(wb2, ws2, 'Sheet1');
XLSX.writeFile(wb2, `报表导出.xlsx`);
}
true