方式一:单独接口,接口封装 特定的service.js
1.下载
//下载
export function getReportTemplate(){return new Promise((resolve, reject) => {axios({method: 'post',url: '/fas/engine/web/fund/final/template',responseType: "blob",headers: {'Content-Type': 'application/json;charset=UTF-8',},}).then((res) => {resolve(res)}).catch(error => {reject(error)});})
}
使用此function
//下载上报的模板
uploadTemplate(){getReportTemplate().then((res) => {console.log("getReportTemplate",res);var blob = new Blob([res.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})var downloadElement = document.createElement('a')//创建一个a 虚拟标签var href = window.URL.createObjectURL(blob) // 创建下载的链接downloadElement.href = href;downloadElement.download = "基金预算编报模板"; // 下载后文件名document.body.appendChild(downloadElement)downloadElement.click() // 点击下载document.body.removeChild(downloadElement) // 下载完成移除元素window.URL.revokeObjectURL(href) // 释放掉blob对象});
},
2.上传
//上传
export function getReport(formData){return new Promise((resolve, reject) => {axios({method: 'post',url: '/fas/engine/web/fund/budget/addReport',data: formData,headers: {'Content-Type': 'multipart/form-data'}}).then((res) => {resolve(res)}).catch(error => {reject(error)});})
}
使用此function, test.vue
<template><el-dialog :destroy-on-close="true" :close-on-click-modal="false" :title="title" :visible.sync="dialogVisible" @closed="closed"><el-upload style="width:100%"ref="upload"class="upload-demo"dragaccept=".xlsx":limit="limit"action="":show-file-list="false":on-change="handleChange":on-remove="handleRemove":http-request="handleUpload":on-exceed="handleExceed":file-list="fileList":before-upload="beforeUpload":auto-upload="false"><i class="el-icon-upload" v-show="!uploadFlag"></i><div class="el-upload__text" v-show="!uploadFlag">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__text" v-show="!uploadFlag">支持格式.xlsx且不超过10MB!</div><div class="my-el-upload__text" v-show="uploadFlag"><span class="filename">{{fileName}}</span> {{fileSize}}<br/><br/><span class="cx">重选</span></div><div class="el-upload__tip" slot="tip"><div>导入说明:</div><div>1.请确定使用最新版本导入数据,否则会提交失败。</div><div>2.请按模板中的约束条件操作,否则会提交失败。</div></div></el-upload><span slot="footer" class="dialog-footer"><!-- <el-button size="mini" @click="dialogVisible = false">取消</el-button> --><el-button size="mini" type="primary" @click="submitUpload()">提交</el-button></span></el-dialog>
</template><script>
import { Message } from "element-ui";
import {getReport} from '@/services/fumtService/fundRunManage/fundCalFormulationService';
import { formatBytes } from "@/utils/util";
export default {name: "fundCalUpload",data() {return {dialogVisible: false,editForm:{},limit:1,uploadFlag:false,fileList: [// {name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}],title:'',fileName:'',fileSize:'',};},methods: {beforeUpload(file) {// console.log(file);// var testmsg = file.name.substring(file.name.lastIndexOf('.')+1);// const extension = testmsg === 'xlsx';// const isLt10M = file.size / 1024 / 1024 < 10;// if(!extension) {// Message.error('上传文件只能是 .xlsx 格式');// }// if(!isLt10M) {// Message.error('上传文件大小不能超过 10MB!');// }},submitUpload() {if(!this.uploadFlag){Message.error("请先选择文件!");} else{this.$refs.upload.submit();}},handleRemove(file, fileList) {this.uploadFlag = false},handleChange(file, fileLists){console.log("----------file",file);console.log("----------fileLists",fileLists);var testmsg = file.name.substring(file.name.lastIndexOf('.')+1);const extension = testmsg === 'xlsx';const isLt10M = file.size / 1024 / 1024 < 10;if(!extension) {Message.error('上传文件只能是 .xlsx 格式');}if(!isLt10M) {Message.error('上传文件大小不能超过 10MB!');}if(extension && isLt10M){this.fileName=file.name;this.fileSize=formatBytes(file.size,2);this.uploadFlag = true;}return extension && isLt10M;},handleUpload(file) {let formDatas = new FormData();formDatas.append("file", file.file);formDatas.append("rid", this.editForm.rid);//这"file" 代表参数名// formDatas.append("user_id", 18); //把后端需要参数全部用这个形式push进去getReport(formDatas).then((res) => {Message.success('上报成功');this.dialogVisible = false;}).catch((err)=>{Message.error(err);})},handleExceed(files, fileList) {this.handleChange(files[0], fileList);// this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);// Message.warning(`当前限制选择 1 个文件!`);},handleClose: function (done) {let self = thisBus.$emit("delCurrentTab", "businessQuery/CntrDetail");},closed(){this.uploadFlag=false;this.fileList= [];this.title='';},show(data,title) {this.title=title;this.dialogVisible = true;this.editForm = JSON.parse(JSON.stringify(data));},submitForm(){this.$refs.upload.submit();}},
};
</script><style scoped lang="less">
/deep/ .el-form-item__content {width: 100%;
}/deep/ .el-upload{width: 100%;
}
/deep/ .el-upload-dragger{width: 100%;
}
.my-el-upload__text:focus{outline: none!important;
}
.my-el-upload__text{// outline: none!important;margin-top:50px;color:#606255;.filename{margin-right: 20px;color: #303133;text-decoration: underline;}.cx{color: #1b65b9;}
}</style>
方式二、封装通用的底层的service.js
重点:
instanceName: "exportExcel",导出excel文件
instanceName: "downloadLog",下载.log后缀的txt文件
// 可声明axios的default配置
export const defaults = defineRequestConfig([{/*** 对参数 `params` 进行序列化* axios 默认做参数序列化时会进行encode 导致某些接口中文参数问题,暂时使用外部覆盖方式解决*/paramsSerializer: (params) => {return qs.stringify(params, { arrayFormat: 'repeat', encode: false })},// 多实例配置interceptors: {request: {// 设置请求头信息onConfig: (config) => {config.headers.Accept = 'application/json'config.headers['Content-Type'] = 'application/json'config.headers['X-Requested-With'] = 'XMLHttpRequest'if (!config.data) config.data = {}return config}},response: {// 请求失败onError: (error) => {const { response } = errorconst { data } = response// 处理请求错误的返回结果const errorObj = {status: response?.status,statusText: response?.statusText,errorCode: data?.errorCode ?? data?.error,errorMessage:data?.errorMessage ?? data?.message ?? data?.error ?? data}// 判断登录超时if (response && response.status === 401) {console.error('登录超时', response)const loginUrl = response?.headers?.loginurl || ''if (loginUrl) {// 跳转登录页window.location.href = loginUrlreturn Promise.reject(error)} else {// 页面刷新window.location.reload()return Promise.reject(error)}}return Promise.reject(errorObj)}}}},{paramsSerializer: (params) => {return qs.stringify(params, { arrayFormat: 'repeat', encode: true })},instanceName: "test",baseURL: '/test',interceptors: {request: {// 设置请求头信息onConfig: (config) => {config.headers.Accept = 'application/json'config.headers['Content-Type'] = 'application/json'config.headers['X-Requested-With'] = 'XMLHttpRequest'if (!config.data) config.data = {}return config}},response: {// 请求失败onError: (error) => {const { response } = errorconst { data } = response// 处理请求错误的返回结果const errorObj = {status: response?.status,statusText: response?.statusText,errorCode: data?.errorCode ?? data?.error ?? data?.code,errorMessage:data?.errorMessage ?? data?.message ?? data?.error ?? data}// 判断登录超时if (response && response.status === 401) {console.error('登录超时', response)const loginUrl = response?.headers?.loginurl || ''if (loginUrl) {// 跳转登录页window.location.href = loginUrlreturn Promise.reject(error)} else {// 页面刷新window.location.reload()return Promise.reject(error)}}return Promise.reject(errorObj)}}}},{paramsSerializer: (params) => {return qs.stringify(params, { arrayFormat: 'repeat', encode: false })},instanceName: "exportExcel",baseURL: '/test',interceptors: {request: {// 设置请求头信息onConfig: (config) => {config.headers.Accept = 'application/json'config.responseType = "blob"config.headers['Content-Type'] = 'application/json;charset=UTF-8'config.headers['X-Requested-With'] = 'XMLHttpRequest'if (!config.data) config.data = {}return config}},response: {onResponse: (response) => {const { data } = response;const str = response?.headers['content-disposition']const oldFileName = buildFileName(str)const filename = response?.headers['Kyy-Hosp-Dip-Filename']response.data = {data: data,filename: filename ? filename : oldFileName}return response},// 请求失败onError: (error) => {const { response } = errorconst { data } = response// 处理请求错误的返回结果const errorObj = {status: response?.status,statusText: response?.statusText,errorCode: data?.errorCode ?? data?.error ?? data?.code,errorMessage:data?.errorMessage ?? data?.message ?? data?.error ?? data}// 判断登录超时if (response && response.status === 401) {console.error('登录超时', response)const loginUrl = response?.headers?.loginurl || ''if (loginUrl) {// 跳转登录页window.location.href = loginUrlreturn Promise.reject(error)} else {// 页面刷新window.location.reload()return Promise.reject(error)}}return Promise.reject(errorObj)}}}},{paramsSerializer: (params) => {return qs.stringify(params, { arrayFormat: 'repeat', encode: true })},instanceName: "downloadLog",baseURL: '/test',interceptors: {request: {// 设置请求头信息onConfig: (config) => {config.headers.Accept = 'application/json'config.headers['Content-Type'] = 'application/octet-stream'if (!config.data) config.data = {}return config}},response: {onResponse: (response) => {const { data } = response;const filename = response?.headers['Kyy-Hosp-Dip-Filename']response.data = {data: data,filename: filename}return response},// 请求失败onError: (error) => {console.log('error', error);const { response } = errorconst { data } = response// 处理请求错误的返回结果const errorObj = {status: response?.status,statusText: response?.statusText,errorCode: data?.errorCode ?? data?.error ?? data?.code,errorMessage:data?.errorMessage ?? data?.message ?? data?.error ?? data}// 判断登录超时if (response && response.status === 401) {console.error('登录超时', response)const loginUrl = response?.headers?.loginurl || ''if (loginUrl) {// 跳转登录页window.location.href = loginUrlreturn Promise.reject(error)} else {// 页面刷新window.location.reload()return Promise.reject(error)}}return Promise.reject(errorObj)}}}},
])const buildFileName = (disposition) => {let result = null;const list = disposition.split(";")list.forEach(item => {if (item.indexOf("filename=") != -1) {const name = item.split("filename=");result = decodeURI(name[1])}});return result;
}
封装接口
export function exportResult(data) {return httpApi({instanceName: 'exportExcel',url: '/**/',method: 'post',data})
}export function downloadSyncLog(params) {return httpApi({instanceName: 'downloadLog',url: '/**/',method: 'get',params})
}
代码中使用:
// 导出数据excel
exportData() {let params = this.getSearchParams();params.count = this.pagesUp.total;//导出下载必填exportResult(params).then(res => {//这个里面的data 的二进制文件 创建一个文件对象let blob = new Blob([res.data || ""], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })let downloadElement = document.createElement('a')//创建一个a 虚拟标签let href = window.URL.createObjectURL(blob) // 创建下载的链接downloadElement.href = href;downloadElement.download = "test文件名"; // 下载后文件名document.body.appendChild(downloadElement)downloadElement.click() // 点击下载document.body.removeChild(downloadElement) // 下载完成移除元素window.URL.revokeObjectURL(href) // 释放掉blob对象this.$message.success('导出成功')}).catch(e => {this.$message.error('导出失败')})
},
// 日志下载
download(row){downloadSyncLog({syncTaskId:row.syncTaskId}).then(res => {let blob = new Blob([res.data || ""], {type: 'application/text'});let downloadElement = document.createElement('a')//创建一个a 虚拟标签let href = window.URL.createObjectURL(blob) // 创建下载的链接downloadElement.href = href;downloadElement.download = row.syncTaskId+'.log'; // 下载后文件名document.body.appendChild(downloadElement)downloadElement.click() // 点击下载document.body.removeChild(downloadElement) // 下载完成移除元素window.URL.revokeObjectURL(href) // 释放掉blob对象this.$message.success('下载成功')}).catch(e => {this.$message.error('下载失败')})
},