vue+element 使用Export2Excel导出表格组件
下载表格组件是根据我自己的业务需求来封装的
使用的是vue中 xlsx 的插件,需要安装新的依赖及配置
仅供参考 不保证和你百分百匹配


安装依赖
npm install -S file-saver xlsx
npm install -D script-loader
下载所需js
链接:https://pan.baidu.com/s/170okRAPiWxQrBvlDEpp7SQ 提取码: gsf5
百度网盘真特喵的是个好东西啊
因为我的子组件引用了该js 如果你不想自己再修改位置,可以跟我一样,
在src中,建立excel文件,将下载的js扔进去

组件调用
直接说调用部分,文章最后会把组件的代码贴出来
父组件引入子组件
import exportTable from '@/components/common/exportTable';
......
components:{
exportTable
}
父组件调用子组件
<export-table ref="childRefName" :export-prepare.sync="exportPrepare" :list-query.sync="listQuery"></export-table>

参数详解
exportPrepare:{
percentage: 0, //导出数据完成的百分比
name:'消耗记录',//导出表格名称
pageType:'pagination',//导出数据获取方式:offset为偏移量、pagination为分页 默认值为pagination
limit:200,//单页数据数量 最大值为200 超过200 按200读取(自定义)或 perPage: 200(根据接口参数决定使用limit/perPage,暂时仅支持limit/perPage)
total:0,//导出数据总数
json_fields: { // excel 表头(具体名称根据实际情况而定)
'耗材编号': 'String',
'耗材品牌': 'String',
'耗材类型': 'String',
'耗材名称': 'String',
'规格型号': 'String',
'耗材属性': 'String',
'耗材价格': 'Number',
'消耗类型': 'String',
'消耗地点': 'String',
'出库仓': 'String',
'目标设备': 'String',
'操作人': 'String',
'操作时间': 'String'
},
json_relationship:{ //导出数据对应的字段名称(具体字段根据实际情况而定 key值与表头保持一致)
'耗材编号': 'supplies_number',
'耗材品牌': 'brand_name',
'耗材类型': 'type',
'耗材名称': 'supplies_name',
'规格型号': 'spec_name',
'耗材属性': 'spec_attribute',
'耗材价格': 'cost',
'消耗类型': 'supplies_type',
'消耗地点': 'out_address',
'出库仓': 'warehouse_name',
'目标设备': 'device_id',
'操作人': 'staff_name',
'操作时间': 'updated_at'
},
param:{},//获取导引数据接口所需的参数
dataList:[]
}
注:json_relationship的值一定与json_fields的值保持一致,否则导出的表会出现空表的问题
listQuery: { // 列表请求数据
where: {},//where是我的接口用到的筛选数据的条件 没有可以直接去掉
page: 1,
limit: 20
}
注:子组件导出数据时页码,会引起父页面修改exportPrepare的param的page、limit参数,使用listQuery进行独立数据深拷贝,子组件的参数变化就不会引起父页面的变化
页面处理导出数据
父组件内获取导出数据的方法
getExcelData(){
this.$refs.exportExcel.index+=1;
if(this.$refs.exportExcel.index<this.$refs.exportExcel.params.length) {
suppliesWaitInExcelData( this.$refs.exportExcel.params[this.$refs.exportExcel.index]).then((response) => {
const data = this.data_ext ? response[this.data_ext].data : response.data;
//data的值,需要根据实际的response数据格式进行赋值
const relationship = this.exportPrepare.json_relationship;
for (let i in data) {
var item = {};
for (let attr in relationship) {
item[attr] = !data[i][relationship[attr]] && data[i][relationship[attr]] !== 0 ? '' : data[i][relationship[attr]];
}
this.exportPrepare.dataList.push(item);
}
this.exportPrepare.percentage = Number((this.exportPrepare.dataList.length / this.exportPrepare.total*100).toFixed(0)) || 0;
this.getExcelData();
})
.catch(e=>{//这里是处理接口获取失败的情况 => 重新执行该条 知道走通(不需要可以把这个部分清空)
console.log('失败了')
this.$refs.exportExcel.index-=1;
this.getExcelData();
})
}
}
注:getExcelData:为固定方法名称,不可以自定义(子组件内有调用 除非两者保持一致)
suppliesWaitInExcelData:获取导出数据的接口api名称,根据具体项目需求更换(接口封装方法不同,调用api方法不同,请根据实际情况修改)
子组件封装
注:子组件中用到this.$parents.doSomeThing()的方式去寻找父组件的方法,所以子组件不能被包裹在别的组件中(包括ele、el-row等element或自定义组件),否则会因为父组件层级问题,找不到对应的父组件方法
或者根据具体情况修改子组件内的方法 ex:this.$parents.$parents.doSomeThing() 多找一层parent 有可能会找到 但是不推荐
<template>
<div id="export-excel">
<el-button type="primary" icon="document" class="export-btn" @click="init">导出数据</el-button>
<el-dialog title="导出" :visible.sync="form.dialogFormVisible" size="tiny" :before-close="handleClose">
<div class="prev-btn right">
<el-progress :percentage="exportPrepare.percentage" style="margin-bottom: 20px;"></el-progress>
<p style="color:#F56C6C;font-size:12px;" v-show="exportTips">数据量过大,推荐选择精确数据下载</p>
<el-button type="primary" @click="exportAction" v-if="exportPrepare.total == exportPrepare.dataList.length">导出</el-button>
<el-button type="primary" class="cancel-action" v-else>导出</el-button>
<el-button @click="handleClose">取消</el-button>
</div>
</el-dialog>
</div>
</template> <script type="application/ecmascript">
export default {
name: "export-excel",
props: {
exportPrepare: {
type: Object
},
listQuery: {
type: Object
} },
data() {
return {
params: [],
paramsItem: {},
index: -1,
// 导出表单所需数据对象
form: {
loading: false,
dialogFormVisible: false,
},
pageType: 'pagination', //获取数据方式 pagination为分页方式 offset为偏移量方式
json_meta: [ // 设置字符集
[{
key: "charset",
value: "utf-8"
}]
], // excel表头
json_data: [], // 要导出的数据
dataList: [], // 要导出的数据
button_text: '', // 导出按钮名称
data_ext: '', // 数据后缀 防止返回的数据格式不是[obj, obj...]
childExportPrepare:{},
exportTips:false,//数据过大提示
};
},
mounted() {
this.pageType = this.exportPrepare.pageType || 'pagination'
this.childExportPrepare = JSON.parse(JSON.stringify(this.listQuery))
},
watch: {
listQuery(newValue, oldValue) {
this.childExportPrepare = JSON.parse(JSON.stringify(this.listQuery))
}
},
methods: {
// 导出初始化
init() {
this.form.dialogFormVisible = true;
this.data_ext = this.exportPrepare.data_ext || '';
this.fetchExportList();
}, // 数据列表分次获取
fetchExportList() {
this.childExportPrepare = JSON.parse(JSON.stringify(this.listQuery))
this.exportPrepare.dataList = [];
this.index = -1;
this.params = [];
this.exportPrepare.percentage = 0;
this.json_data = [];
if (this.pageType == 'offset') {
if(this.exportPrepare.limit){
if (this.exportPrepare.total > this.exportPrepare.limit) {
this.json_data = [];
let param = {}
param = this.childExportPrepare
for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.limit); i++) {
if(i>=20){
this.exportTips = true;
}else{
this.exportTips = false;
}
if(this.exportPrepare.limit>200){
this.exportPrepare.limit = 200;
}
var startPage = 0,
endlimit = 0;
startPage = i * this.exportPrepare.limit;
this.$set(param,'page',startPage)
endlimit = this.exportPrepare.limit;
if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.limit) - 1 && this.exportPrepare.total % this.exportPrepare.limit != 0) {
endlimit = this.exportPrepare.total % this.exportPrepare.limit
}
this.$set(param,'limit',endlimit)
let paramList = {page:param.page,limit:param.limit};
this.form.loading = true;
this.params.push(Object.assign(paramList,this.childExportPrepare));
}
this.$parent.$parent.getExcelData()
this.json_data = this.exportPrepare.dataList;
} else { this.json_data = [];
this.params = [];
this.childExportPrepare.page = 0;
this.childExportPrepare.limit = this.exportPrepare.total;
let param = [];
param.page = 0;
param.limit = this.exportPrepare.total;
let paramList = {page:param.page,limit:param.limit};
this.params.push(Object.assign(paramList,this.childExportPrepare));
this.form.loading = true;
this.$parent.$parent.getExcelData();
this.json_data = this.exportPrepare.dataList;
}
}else{
if (this.exportPrepare.total > this.exportPrepare.perPage) {
this.json_data = [];
let param = {};
param = this.childExportPrepare
for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage); i++) {
if(i>=20){
this.exportTips = true;
}else{
this.exportTips = false;
}
if(this.exportPrepare.perPage>200){
this.exportPrepare.perPage = 200;
}
var startPage = 0,
endlimit = 0;
startPage = i * this.exportPrepare.perPage;
this.$set(param,'page',startPage)
endlimit = this.exportPrepare.perPage;
if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage) - 1 && this.exportPrepare.total % this.exportPrepare.perPage != 0) {
endlimit = this.exportPrepare.total % this.exportPrepare.perPage
}
this.$set(param,'perPage',endlimit)
let paramList = {page:param.page,perPage:param.perPage};
this.form.loading = true;
this.params.push(Object.assign(paramList,this.childExportPrepare));
}
this.$parent.$parent.getExcelData()
this.json_data = this.exportPrepare.dataList;
} else {
this.json_data = [];
this.params = [];
this.childExportPrepare.page = 0;
this.childExportPrepare.limit = this.exportPrepare.total;
let param = [];
param.page = 0;
param.perPage = this.exportPrepare.total;
let paramList = {page:param.page,perPage:param.perPage};
this.params.push(Object.assign(paramList,this.childExportPrepare));
this.form.loading = true;
this.$parent.$parent.getExcelData();
this.json_data = this.exportPrepare.dataList;
}
}
} else {
if(this.exportPrepare){
if (this.exportPrepare.total > this.exportPrepare.limit) {
this.json_data = [];
let param = {}
param = this.childExportPrepare
for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.limit); i++) {
if(i>=20){
this.exportTips = true;
}else{
this.exportTips = false;
}
if(this.exportPrepare.limit>200){
this.exportPrepare.limit = 200;
}
let startPage = 0, endlimit = 0;
startPage = i + 1;
this.$set(param,'page',startPage)
endlimit = this.exportPrepare.limit;
if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.limit) - 1 && this.exportPrepare.total % this.exportPrepare.limit != 0) {
endlimit = this.exportPrepare.total % this.exportPrepare.limit
}
this.$set(param,'limit',endlimit)
let paramList = {page:param.page,limit:param.limit};
this.form.loading = true;
this.params.push(Object.assign(paramList,this.childExportPrepare));
}
this.$parent.$parent.getExcelData()
this.json_data = this.exportPrepare.dataList;
} else {
this.json_data = [];
this.params = [];
this.childExportPrepare.page = 1;
this.childExportPrepare.limit = this.exportPrepare.total;
let param = [];
param.page = 1;
param.limit = this.exportPrepare.total;
let paramList = {page:param.page,limit:param.limit};
this.params.push(Object.assign(paramList,this.childExportPrepare));
this.form.loading = true;
this.$parent.$parent.getExcelData();
this.json_data = this.exportPrepare.dataList;
}
}else{
if (this.exportPrepare.total > this.exportPrepare.perPage) {
this.json_data = [];
let param = {}
param = this.childExportPrepare
for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage); i++) {
if(i>=20){
this.exportTips = true;
}else{
this.exportTips = false;
}
if(this.exportPrepare.perPage>200){
this.exportPrepare.perPage = 200;
}
var startPage = 0,
endlimit = 0;
startPage = i + 1;
this.$set(param,'page',startPage)
endlimit = this.exportPrepare.perPage;
if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage) - 1 && this.exportPrepare.total % this.exportPrepare.perPage != 0) {
endlimit = this.exportPrepare.total % this.exportPrepare.perPage
}
this.$set(param,'perPage',endlimit)
let paramList = {page:param.page,perPage:param.perPage};
this.form.loading = true;
this.params.push(Object.assign(paramList,this.childExportPrepare));
}
this.$parent.$parent.getExcelData()
this.json_data = this.exportPrepare.dataList; } else {
this.json_data = [];
this.params = [];
this.childExportPrepare.page = 1;
this.childExportPrepare.limit = this.exportPrepare.total;
let param = [];
param.page = 1;
param.perPage = this.exportPrepare.total;
let paramList = {page:param.page,perPage:param.perPage};
this.params.push(Object.assign(paramList,this.childExportPrepare));
this.form.loading = true;
this.$parent.$parent.getExcelData();
this.json_data = this.exportPrepare.dataList;
}
}
}
}, //导出
exportAction() {
if (this.exportPrepare.total == this.json_data.length) {
require.ensure([], () => {
const {
export_json_to_excel
} = require('../../excel/Export2Excel');
const tHeader = [];
for (let i in this.exportPrepare.json_fields) {
tHeader.push(i);
}
if (this.json_data.length < 1) {
this.fetchExportList();
return
}
const list = this.json_data;
const data = this.formatJson(tHeader, list);
export_json_to_excel(tHeader, data, this.exportPrepare.name || '导出数据');
this.form.loading = true;
setTimeout(() => {
this.form.loading = false;
this.$notify({
title: '成功',
message: '导出成功',
type: 'success',
duration: 1500
});
this.form.dialogFormVisible = false;
this.json_data = [];
this.dataList = [];
this.exportPrepare.dataList = [];
}, 500);
})
}
}, formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => v[j]))
}, // 关闭导出对话框
handleClose() {
this.form.dialogFormVisible = false;
this.exportPrepare.dataList = [];
this.json_data = [];
this.dataList = [];
this.params = [];
this.exportPrepare.percentage = 0;
}
}
}
</script> <style scoped="scoped" lang="scss">
.cancel-action {
opacity: .4;
} .right {
text-align: right;
}
#export-excel{
float: right;
}
</style>
vue+element 使用Export2Excel导出表格组件的更多相关文章
- Vue+element ui table 导出到excel
需求: Vue+element UI table下的根据搜索条件导出当前所有数据 参考: https://blog.csdn.net/u010427666/article/details/792081 ...
- vue+element UI如何导出excel表
导出excel表应按如下规则 首先要先安装如下依赖 npm install --save xlsx npm install --save file-saver 接下在在你的代码中去引用这两个 impo ...
- 封装Vue Element的form表单组件
前两天封装了一个基于vue和Element的table表格组件,阅读的人还是很多的,看来大家都是很认同组件化.高复用这种开发模式的,毕竟开发效率高,代码优雅,逼格高嘛.虽然这两天我的心情很糟糕,就像& ...
- Vue+element 实现文件导出xlsx格式
傻瓜教程: 第一步:安装两个依赖包 npm install --save xlsx file-saver 第二步:建立一个Vue文件,导入以下代码即可 <template> <d ...
- vue+element 表单封成组件(1)
作为一名刚接触vue不到一个月的菜鸟,思想还没有从操作DOM转变为数据驱动,看vue的代码处处别扭.组里为了让我熟悉vue交给了我一个将element 表单封装成组件的练手任务.由于开发过程中遇到的表 ...
- 封装Vue Element的upload上传组件
本来昨天就想分享封装的这个upload组件,结果刚写了两句话,就被边上的同事给偷窥上了,于是在我全神贯注地写分享的时候他就神不知鬼不觉地突然移动到我身边,腆着脸问我在干啥呢.卧槽你妈,当场就把我吓了一 ...
- vue中把table导出表格excel
1.首先下载2个js,我的百度网盘有 2.安装依赖 npm install -S file-saver xlsx(这里其实安装了2个依赖) npm install -D script-loader 3 ...
- vue+element tree(树形控件)组件(2)
今天记录组件的代码和一个调用它的父组件的代码,接口接收数据直接传element直接能用的,也就是经过上一章函数处理过的数据以下是代码 父组件 <template> <commonfi ...
- vue+element 表单封成组件(2)
今天我们继续把时间选择器,多选框和单选框加上 父组件(在昨天的基础上增加): <template> <el-form :model="ruleForm" ref= ...
随机推荐
- PHP中获取数组中单列的值
PHP中获取数组中单列的值如下: 利用PHP中的数组函数 array_column():返回数组中某个单列的值.(PHP 5.5+适用) 语法: array_column(array,column_k ...
- js调用后台接口进行下载
js调用后台接口一定不能用ajax location.href=$$pageContextPath +'downfile/down.do?filname='+row.fileUrl;
- ubuntu14.04+安卓7.1(全志源码)+openjdk-8编译
题记:编译花了将近4小时,所以编译源码是很费时的哦,可以在编译的时候可以学习其他的知识 编译环境准备 软件:WorkStation10 系统:ubuntu14.04 内存:8G 处理器:4个 磁盘大小 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型
笔记 2.技术选型和学后水平 简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度, 1.IDEA JDK8 Maven SpringBoot基础 Linux 2.理 ...
- IPTV系统的VOD与TV业务性能测试
IPTV的未来发展正在成为业界的焦点话题.据市场研究公司MRG的统计,全球IPTV用户将由2004年的200万增加至2010年的2000万,预计全球IPTV市场2005-2010年的复合增长率为102 ...
- redis的日常操作(1)
一.简介 [概述] redis是一种nosql数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,并且他比memcached支持更多的数据结构(string ...
- 关于绕过cookie 同源策略,和同时向前台返回图片和脚本的解决方案
绕过cookie的同源策略 向前端写入脚本时使用domain来绕过同源策略. 比如 domain= baidu.com .次脚本生成的cookie可以在 *.baidu.com中使用 /// < ...
- Java中流的操作练习
文件中的学生信息 学生信息存储在TXT文件中,我们需要对信息进行基本的,增.删.改.查,全部显示操作. 1.学生类/Student package com.yujiao.student; public ...
- solr设置分片和副本
numShards:分片数 replicationFactor:每个分片下的副本数 maxShardsPerNode:当numShards为1,replicationFactor为3时,maxShar ...
- ipcs查看消息队列命令
修改消息队列大小: root:用户: /etc/sysctl.conf kernel.msgmnb =4203520 #kernel.msgmnb =3520 kernel.msgmni = 2878 ...