<!--
|
* @Descripttion: 文件导出
|
* @version: 1.1
|
* @Author: sakuya
|
* @Date: 2022年5月24日16:20:12
|
* @LastEditors: sakuya
|
* @LastEditTime: 2022年6月13日17:32:05
|
-->
|
|
<template>
|
<slot :open="open">
|
<el-button type="primary" plain @click="open">导出</el-button>
|
</slot>
|
<el-drawer v-model="dialog" title="导出" :size="400" direction="rtl" append-to-body destroy-on-close>
|
<el-main style="padding: 0 20px 20px 20px;">
|
<div v-loading="downLoading" element-loading-text="正在处理中...">
|
<div v-if="downLoading && progress" style="position: absolute;width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;z-index: 3000;">
|
<el-progress :text-inside="true" :stroke-width="20" :percentage="downLoadProgress" style="width: 100%;margin-bottom: 120px;"/>
|
</div>
|
<el-tabs>
|
<el-tab-pane label="常规" lazy>
|
<el-form label-width="100px" label-position="left" style="margin: 10px 0 20px 0;">
|
<el-form-item label="文件名">
|
<el-input v-model="formData.fileName" placeholder="请输入文件名" />
|
</el-form-item>
|
<el-form-item label="文件类型">
|
<el-select v-model="formData.fileType" placeholder="请选择文件类型">
|
<el-option v-for="item in fileTypes" :key="item" :label="'*.'+item" :value="item" />
|
</el-select>
|
</el-form-item>
|
<slot name="form" :formData="formData"></slot>
|
</el-form>
|
<el-button v-if="async" type="primary" size="large" icon="el-icon-plus" style="width: 100%;" @click="download" :loading="asyncLoading">发起导出任务</el-button>
|
<el-button v-else type="primary" size="large" icon="el-icon-download" style="width: 100%;" @click="download">下 载</el-button>
|
</el-tab-pane>
|
<el-tab-pane label="列设置" v-if="columnData.length>0" lazy>
|
<columnSet :column="columnData"></columnSet>
|
</el-tab-pane>
|
<el-tab-pane label="其他参数" v-if="data && showData" lazy>
|
<el-descriptions :column="1" border size="small">
|
<el-descriptions-item v-for=" (val, key) in data" :key="key" :label="key">{{val}}</el-descriptions-item>
|
</el-descriptions>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
</el-main>
|
|
</el-drawer>
|
</template>
|
|
<script>
|
import columnSet from './column'
|
|
export default {
|
components: {
|
columnSet
|
},
|
props: {
|
apiObj: { type: Object, default: () => {} },
|
fileName: { type: String, default: "" },
|
fileTypes: { type: Array, default: () => ['xlsx'] },
|
data: { type: Object, default: () => {} },
|
showData: { type: Boolean, default: false },
|
async: { type: Boolean, default: false },
|
column: { type: Array, default: () => [] },
|
blob: { type: Boolean, default: false },
|
progress: { type: Boolean, default: true }
|
},
|
data() {
|
return {
|
dialog: false,
|
formData: {
|
fileName: this.fileName,
|
fileType: this.fileTypes[0]
|
},
|
columnData: [],
|
downLoading: false,
|
downLoadProgress: 0,
|
asyncLoading: false
|
}
|
},
|
watch:{
|
'formData.fileType'(val) {
|
if(this.formData.fileName.includes(".")){
|
this.formData.fileName = this.formData.fileName.substring(0, this.formData.fileName.lastIndexOf('.')) + "." + val
|
}else{
|
this.formData.fileName = this.formData.fileName + "." + val
|
}
|
}
|
},
|
mounted() {
|
|
},
|
methods: {
|
open() {
|
this.dialog = true
|
this.formData = {
|
fileName: (this.fileName?this.fileName:(new Date().getTime()+'')) + "." + this.fileTypes[0],
|
fileType: this.fileTypes[0]
|
}
|
this.columnData = JSON.parse(JSON.stringify(this.column))
|
},
|
close() {
|
this.dialog = false
|
},
|
download() {
|
let columnArr = {
|
column: this.columnData.filter(n => !n.hide).map(n => n.prop).join(",")
|
}
|
let assignData = {...this.data, ...this.formData, ...columnArr}
|
if(this.async){
|
this.asyncDownload(this.apiObj, this.formData.fileName, assignData)
|
}else if(this.blob){
|
this.downloadFile(this.apiObj, this.formData.fileName, assignData)
|
}else{
|
this.linkFile(this.apiObj.url, this.formData.fileName, assignData)
|
}
|
},
|
linkFile(url, fileName, data={}){
|
let a = document.createElement("a")
|
a.style = "display: none"
|
a.target = "_blank"
|
//a.download = fileName
|
a.href = url + this.toQueryString(data)
|
document.body.appendChild(a)
|
a.click()
|
document.body.removeChild(a)
|
},
|
downloadFile(apiObj, fileName, data={}){
|
this.downLoading = true
|
var _this = this
|
apiObj.get(data, {
|
responseType: 'blob',
|
onDownloadProgress(e){
|
if(e.lengthComputable){
|
_this.downLoadProgress = parseInt(e.loaded / e.total * 100)
|
}
|
}
|
}).then(res => {
|
this.downLoading = false
|
this.downLoadProgress = 0
|
let url = URL.createObjectURL(res)
|
let a = document.createElement("a")
|
a.style = "display: none"
|
a.target = "_blank"
|
a.download = fileName
|
a.href = url
|
document.body.appendChild(a)
|
a.click()
|
document.body.removeChild(a)
|
URL.revokeObjectURL(url)
|
}).catch(err => {
|
this.downLoading = false
|
this.downLoadProgress = 0
|
this.$notify.error({
|
title: '下载文件失败',
|
message: err
|
})
|
})
|
},
|
asyncDownload(apiObj, fileName, data={}){
|
this.asyncLoading = true
|
apiObj.get(data).then(res => {
|
this.asyncLoading = false
|
if(res.code == 200){
|
this.dialog = false
|
this.$msgbox({
|
title: "成功发起任务",
|
message: `<div><img style="height:200px" src="img/tasks-example.png"/></div><p>已成功发起导出任务,您可以操作其他事务</p><p>稍后可在 <b>任务中心</b> 查看执行结果</p>`,
|
type: "success",
|
confirmButtonText: "知道了",
|
dangerouslyUseHTMLString: true,
|
center: true
|
}).catch(() => {})
|
}else{
|
this.$alert(res.message || "未知错误", "发起任务失败", {
|
type: "error",
|
center: true
|
}).catch(() => {})
|
}
|
}).catch(() => {
|
this.asyncLoading = false
|
})
|
},
|
toQueryString(obj){
|
let arr = []
|
for (var k in obj) {
|
arr.push(`${k}=${obj[k]}`)
|
}
|
return (arr.length>0?"?":"") + arr.join('&')
|
}
|
}
|
}
|
</script>
|
|
<style>
|
|
</style>
|