在前端开发的时候,经常会遇到根据当前的table数据导出excel表格功能。一般导出功能都是有后端er通过接口形式去完成,基于性能和业务场景,有时候会需要纯前端进行导出。

本文主要针对两个开发场景进行描述:1、在没有任何UI框架的开发场景;2、基于element ui或者element plus的框架的开发场景。

一、在没有任何UI框架的开发场景

下面就是在实际的项目中纯前端使用vue-json-excel插件来实现简单Excel表格的导出功能,此组件中实现的方法使用HTML表格绘制.xls文件,Microsoft Excel不再将HTML识别为本机内容,因此在打开文件之前将显示一条警告消息,并且无法避免此警告消息。

vue-json-excel属性列表

属性名 数据类型 描述 默认值
data Array 要导出的数据
fields Object 要导出的JSON对象中的字段。如果未提供,则将导出JSON中的所有属性。
export-fields (exportFields) Object 用于修复使用变量字段的其他组件的问题,例如vee-validate。exportFields与字段完全一样。
type string Mime类型[xls、csv]。 xls
name string 要导出的文件名。 data.xls
header string/Array 数据的标题。可以是字符串(一个标题)或字符串数​​组(多个标题)。
title(已弃用) string/Array 和header一样,title是为了追溯兼容性而保留的,但由于与HTML5的title属性冲突,不推荐使用。
footer string/Array 数据的页脚。可以是字符串(一个页脚)或字符串数​​组(多个页脚)。
default-value (defaultValue) string 当行没有字段值时用作回退。 ''
worksheet string 工作表选项卡的名称。 'Sheet1'
fetch Function 下载前获取数据的回调,如果它被设置它在按下鼠标之后和下载过程之前立即运行。
重要提示:仅在未定义数据属性时才有效。
before-generate Function 回调以在生成/获取数据之前调用方法,例如:显示加载进度。
before-finish Function 在下载框弹出前回调调用方法,例如:隐藏加载进度。
stringifyLongNum Boolean 长度较长的数字和小数(解决数字精度丢失问题),默认:false。
escapeCsv Boolean 这会转义CSV值,以修复数字字段的一些excel问题。但这将用“=”和“and”包装每个csv数据,以避免您必须将此属性设置为false。默认值:true

1、安装依赖

1
2
3
4
5
npm install vue-json-excel

# 或者使用cnpm(淘宝镜像),安装速度更快,推荐使用

cnpm install vue-json-excel

2、在vue项目的入口文件(main.js)中引入

1
2
3
4
5

import Vue from 'vue'
import JsonExcel from 'vue-json-excel'

Vue.component('downloadExcel', JsonExcel)

3、在业务模板中使用

1
2
3
4
5
6
<download-excel
:data= "json_data"
:fields= "json_fields"
name= "用户统计列表">
导出Excel
</download-excel>

标签属性说明

  • name=“用户统计列表” => 导出Excel文件的文件名
  • :fields = “json_fields” => Excel中表头的名称
  • :data = “json_data” => 导出的数据

4、Excel表格表头的设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default{
data(){
return{
json_fields: { //导出Excel表格的表头设置
'序号': 'type',
'姓名': 'userName',
'年龄': 'age',
'手机号': 'phone',
'注册时间': 'createTime',
},
}
}
}

5、Excel表格中的数据

1
2
3
4
5
6
7
8
9
10
11
12
export default{
data(){
return{
json_data:[
{"userName":"张三","age":18,"gender":"phone":15612345612,"createTime":"2023-06-12 15:02:52"},
{"userName":"李四","age":17,"gender":"phone":15612345613,"createTime":"2023-06-12 15:02:52"},
{"userName":"王五","age":19,"gender":"phone":15612345615,"createTime":"2023-06-12 15:02:52"},
{"userName":"赵六","age":18,"gender":"phone":15612345618,"createTime":"2023-06-12 15:02:52"},
]
}
}
}

6、HTML结构及组件应用

HTML的内容,通过isExport来判断显示哪一个(样式就自己去写了)

1
2
<button v-if="isExport" @click="nodaochuBtn()" type="primary">导出Excel</button>
<download-excel v-else class="blueBtn" :data="json_data" :fields = "json_fields" worksheet = "My Worksheet" name = "用户信息列表">导出Excel</download-excel>

二、基于element ui或者element plus的框架的开发场景

(一)、导出一个excel表

1、安装依赖

1
npm install --save xlsx file-saver

2、在需要的组件内引入

1
2
import FileSaver from "file-saver";
import XLSX from "xlsx";

3、使用—必须保证表格格式对应,不然报错

4、ElementUI的html结构

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
<template>
<div>
<!-- 导出按钮 -->
<div class="toexcel">
<el-button @click="exportExcel" type="primary" class="button" style="width:70px;position:absolute;top:0;right:30px">导出</el-button>
</div>
<el-table
class="table"
:data="tableData"
border
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</div>
</template>

javascript代码:

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
import FileSaver from "file-saver";
import XLSX from "xlsx";
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
};
},
methods: {
// 导出表格所用
exportExcel() {
// 设置当前日期
let time = new Date();
let year = time.getFullYear();
let month = time.getMonth() + 1;
let day = time.getDate();
let name = year + "" + month + "" + day;
// console.log(name)
/* generate workbook object from table */
// .table要导出的是哪一个表格
var wb = XLSX.utils.table_to_book(document.querySelector(".table"));
/* get binary string as output */
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array"
});
try {
// name+'.xlsx'表示导出的excel表格名字
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
name + ".xlsx"
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout;
}
}
};

css代码

1
2
3
4
5
6
7
/* 导出按钮 */
.toexcel {
cursor: pointer;
cursor: hand;
width: 70px;
height: 34px;
}

(二)、导出多级标题多sheet页excel

html和css部分大部分都是相同的,只有JavaScript代码部分不同,下面主要是针对创建工作簿部分的代码,其他代码可以参考导出一个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
exportExcel() {
// 创建工作蒲
let workbook = XLSX.utils.book_new();
for (let i = 0; i < 3; i++) {
// 根据table的id创建sheet页,并将sheet添加到工作蒲中
let tableSheet = XLSX.utils.table_to_sheet(document.querySelector('#table'));
// 生成sheet页的名称
XLSX.utils.book_append_sheet(workbook, tableSheet, 'sheet名' + i);
}
// 创建输出对象,excel后缀为xlsx
let wbOut = XLSX.write(wordbook, {
bookType: 'xlsx',
bookSST: true,
type: 'array'
});
try {
// 通过window以流的方式导出工作蒲输出对象
window.saveAs(
new Blob([wbOut], { type: 'application/octet-stream' }), 'excel名.xlsx'
);
} catch (e) {
if (typeof console !== 'undefined') console.log(e, wbOut);
}
}