导出组件的封装
1.其本质还是调用接口拿到excel文件流做处理—exportFile方法在前面的文章中有用到
request({
url: this.url,
method: 'post',
data: data,
responseType: 'blob'
})
.then((res) => {
this.loading = false
exportFile(res)
this.visible = false
})
.catch((err) => {
this.loading = false
})
2.案例如下
<!--使用方式-->
<!--
<template>
<excel-export
:exportSize="100"//导出数据条数,默认500条
:cols="exportData.cols"//备选的所有导出列
formKey="ProjectApproval"//填写对应表单时后台提供的实体对象名称
url="/xxx"//导出地址
:ids="['id1','id2']"//勾选导出时,每一行数据的Id,可选传,传入空数组或者不传,导出所有
:searchParams="{name:'',code:''}"//查询条件
</excel-export>
</template>
<script>
export default {
data(){
return {
exportData: {
visible:false,
cols:[
{
columnComment:"项目编号",//每一列的中文名称
columnName:"prjCode"//每一列对应的字段
},
{
columnComment:"项目名称",
columnName:"prjName",
},
{
columnComment:"项目简称",
columnName:"prjSimpleName"
},
{
columnComment:"项目总投资(万元)",
columnName:"prjAllInvest"
},
{
columnComment:"项目类型",
columnName:"prjClass",
dic:'prj_class'//是否需要进行字典的转换
},
{
columnComment:"项目经理",
columnName:"prjManageUserName"
},
{
columnComment:"填写日期",
columnName:"createDate"
},
{
columnComment:"填写人",
columnName:"userFullname"
},
]
},
}
}
}
</script>
-->
<template>
<div class="export">
<fks-button @click="open" v-bind="$attrs">
<svg-icon
style="vertical-align: middle; margin-right: 8px"
icon-class="export"
></svg-icon>
<span style="vertical-align: middle">{{ LANG.EXPORT }}</span>
</fks-button>
<fks-dialog
:visible.sync="visible"
@opened="handleOpened"
@close="handleClose"
id="dialog"
>
<div slot="title">
<svg-icon
style="vertical-align: middle; margin-right: 8px; color: #2f53ea"
icon-class="export"
></svg-icon>
<span style="color: #191919">{{ LANG.EXPORT }}</span>
</div>
<fks-form ref="form" :model="form" :rules="rules">
<fks-form-item
lead
:span="12"
label="导出文件名称"
prop="excelName"
label-width="120px"
>
<fks-input
v-model="form.excelName"
placeholder="请输入导出文件名称"
maxlength="50"
></fks-input>
</fks-form-item>
<fks-form-item
:span="12"
label="sheet名称"
prop="sheetName"
label-width="120px"
>
<fks-input
v-model="form.sheetName"
placeholder="请输入sheet名称"
maxlength="50"
></fks-input>
</fks-form-item>
</fks-form>
<div class="transfer-container">
<fks-transfer
ref="transfer"
v-model="value"
:data="allCols"
:titles="['备选导出列', '导出列']"
>
<span slot-scope="{ option }">
{{ option.columnComment }}
</span>
</fks-transfer>
</div>
<div slot="footer" align="right">
<fks-button type="primary" @click="handleExport" :loading="loading"
><i class="fks-icon-check" style="margin-right: 8px"></i
><span>{{ LANG.EXPORT }}</span>
</fks-button>
</div>
</fks-dialog>
</div>
</template>
<script>
import request from '@/utils/request'
import Sortable from 'sortablejs'
import { exportFile } from '@/utils/file'
export default {
inheritAttrs: false,
props: {
//备选所有列
cols: {
type: Array,
required: true
},
//业务对象
formKey: {
type: String,
required: true
},
//勾选的Id
ids: {
type: Array,
default() {
return []
}
},
//导出地址
url: {
type: String,
required: true
},
//导出行数目
exportSize: {
type: Number,
default: 500
},
searchParams: {
type: Object,
default() {
return {}
}
}
},
data() {
let value = []
let allCols = this.cols.map((item, index) => {
item.key = index
//加上key
value.push(index)
return item
})
return {
visible: false,
loading: false,
allCols: allCols, //所有列
value: value, //右侧导出列的key数组
form: {
excelName: '',
sheetName: ''
}, //导出文件名称
rules: {
excelName: [
{
required: true,
message: "请输入文件名称",
trigger: 'blur'
}
]
}
}
},
methods: {
//打开弹窗
open() {
this.visible = true
// this.$emit("update:visible", true)
},
handleExport() {
// 只是为了查看数据打印
let exportFields = []
this.value.forEach((key) => {
let obj = this.allCols.find((item) => {
return item.key === key
})
exportFields.push(obj)
})
let dataa = {
exportFields: exportFields,
excelName: this.form.excelName,
sheetName: this.form.sheetName,
formKey: this.formKey,
ids: this.ids,
exportSize: this.exportSize
// searchParams: searchParams
}
console.log(dataa)
// 只是为了查看数据打印-结束
this.$refs.form.validate((valid) => {
if (valid) {
let exportFields = []
this.value.forEach((key) => {
let obj = this.allCols.find((item) => {
return item.key === key
})
exportFields.push(obj)
})
if (!exportFields.length) {
this.$message.error('请至少选择一个导出列')
return
}
//过滤掉查询条件为空或者null的条件
let searchParams = {}
Object.keys(this.searchParams).forEach((key) => {
if (
this.searchParams[key] !== null &&
this.searchParams[key] !== ''
) {
searchParams[key] = this.searchParams[key]
}
})
let data = {
exportFields: exportFields,
excelName: this.form.excelName,
sheetName: this.form.sheetName,
formKey: this.formKey,
ids: this.ids,
exportSize: this.exportSize,
searchParams: searchParams,
// formKey: this.formKey,
// field: item.searchName,S
}
// let query = []
// this.cols.forEach((item) => {
// let queryItem = {
// content: '',
// field: item.field,
// symbol: 'like'
// }
// query.push(queryItem)
// })
// let data = {
// formKey: this.formKey,
// page: '1',
// query,
// size: '999'
// }
this.loading = true
request({
url: this.url,
method: 'post',
data: data,
responseType: 'blob'
})
.then((res) => {
console.log('res')
console.log(res)
this.loading = false
exportFile(res)
this.visible = false
})
.catch((err) => {
this.loading = false
console.log(err)
})
} else {
this.$message.error('请检查表单是否合格')
}
})
},
handleOpened() {
const transfer = this.$refs.transfer.$el
const rightPanel = transfer
.getElementsByClassName('fks-transfer-panel')[1]
.getElementsByClassName('fks-transfer-panel__body')[0]
const rightEl = rightPanel.getElementsByClassName(
'fks-transfer-panel__list'
)[0]
Sortable.create(rightEl, {
animation: 150,
onEnd: (evt) => {
const { oldIndex, newIndex } = evt
const oldValue = this.value[oldIndex]
//删除原来的数据
this.value.splice(oldIndex, 1)
//将数据新增到指定索引位置
this.value.splice(newIndex, 0, oldValue)
}
})
rightPanel.ondragover = (ev) => {
ev.preventDefault()
}
rightPanel.ondrop = (ev) => {
ev.preventDefault()
}
},
handleClose() {
// this.$emit("update:visible", false)
this.$refs.form.resetFields()
this.visible = false
}
}
}
</script>
<style>
</style>
<style lang="scss" scoped>
.export {
display: inline-block;
margin-left: 10px;
// margin-right: 10px;
}
/deep/ .fks-dialog {
text-align: left;
.fks-dialog__header {
height: 56px;
position: relative;
.fks-dialog__headerbtn {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
.fks-dialog__body {
overflow: hidden;
}
.fks-form {
// margin-top: 15px;
margin-bottom: 8px;
}
.fks-form-item__label {
text-align: left !important;
}
.transfer-container {
height: 425px;
margin: 0 auto;
display: flex !important;
justify-content: space-between;
.fks-transfer__buttons {
padding: 0 16px;
width: 32px;
position: relative;
.fks-transfer__button {
background: #ffffff;
border-color: #acbaf7;
color: #2f53ea;
&:hover {
border-color: #2f53ea;
color: #2f53ea;
}
&.is-disabled {
border-color: #eeeeee;
color: #cccccc !important;
background: #f5f5f5 !important;
}
&:active {
background-color: #eaeefd;
}
&:nth-child(1) {
&.is-disabled {
width: 32px;
height: 32px;
background: #f5f5f5;
color: #f5f5f5;
}
position: absolute;
top: -10px;
width: 32px;
min-width: 32px !important;
height: 32px;
text-align: center;
span {
position: absolute;
width: 100%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
i {
width: 100%;
left: 50%;
//top:50%;
}
}
/*background:#e7ebfd;*/
/*color:#294be8;*/
/*border-radius: 4px;*/
}
&:nth-child(2) {
&.is-disabled {
width: 32px;
height: 32px;
text-align: center;
background: #f5f5f5;
color: #f5f5f5;
}
position: absolute;
top: -50px;
width: 32px;
height: 32px;
min-width: 32px !important;
span {
position: absolute;
width: 100%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
i {
margin-left: 0;
width: 100%;
right: 50%;
top: 50%;
}
}
}
margin-left: 0 !important;
display: block;
.fks-icon-arrow-left {
margin-right: 8px;
}
}
}
.fks-transfer-panel {
width: 416px;
border: 1px solid #dddddd;
.fks-transfer-panel__header {
background: #ffffff;
height: 48px;
line-height: 48px;
.fks-checkbox__input {
width: 16px;
height: 16px;
top: -1px;
.fks-checkbox__inner {
width: 100%;
height: 100%;
&::before {
top: 1px;
}
&::after {
top: 2px;
}
}
}
.fks-checkbox {
height: 48px;
align-items: center;
.fks-checkbox__label {
line-height: 48px;
font-size: 14px;
color: #555555;
span {
color: #999999;
font-size: 14px;
}
}
}
}
.fks-transfer-panel__body {
height: 425px !important;
.fks-transfer-panel__item {
width: 100%;
height: 36px;
.fks-checkbox__input {
width: 16px;
height: 16px;
line-height: 0;
.fks-checkbox__inner {
width: 100%;
height: 100%;
&::after {
top: 2px;
}
}
}
.fks-checkbox__label {
font-size: 14px;
color: #555555;
}
}
.fks-transfer-panel__list {
height: calc(100% - 48px);
overflow-x: hidden;
/*overflow-y: overlay;*/
}
.fks-transfer-panel__empty {
color: #999999;
margin-top: 130px;
}
}
}
}
}
</style>