vue如何通过$http的post方法请求下载二进制的Excel文件

方式一:单独接口,接口封装 特定的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('下载失败')})
},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分类问题:人工神经网络(ANN)+BP算法(误差后向传播)+考试例题讲解

学习链接:分类问题:人工神经网络(ANN)+BP算法(误差后向传播)+考试例题讲解 资料链接:链接:https://pan.baidu.com/s/1ijvMQmwtRgLO4KDSsNODMw 提取码:vyok 神经网络的应用非常的广,它核心思想非常简单,就是人是如何认知感知并且处理这个世界中的现实问题的。…

[C++] opencv - copyTo函数介绍和使用案例

copyTo函数介绍 copyTo函数是OpenCV库中的一个成员函数&#xff0c;用于将一个Mat对象的内容复制到另一个Mat对象中。 函数原型&#xff1a; void cv::Mat::copyTo(OutputArray m) const;void cv::Mat::copyTo(OutputArray m, InputArray mask) const; 参数说明&#xff1a;…

大创项目推荐 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

数据库的设计模式

数据库的设计模式常用于处理特定类型的数据和需求。以下是一些常见的模式&#xff1a; 1. EAV&#xff08;Entity-Attribute-Value&#xff09; 用途&#xff1a;用于非结构化或高度可变的数据模型。描述&#xff1a;实体以行形式存储&#xff0c;属性和值作为额外的表格列存…

01|js包管理工具和原理分析:npm安装机制及企业级部署私服原理

01 | js包管理工具和原理分析&#xff1a;npm安装机制及企业级部署私服原理 前端工程化离不开 npm 或者 Yarn 管理工具 通过script串联起各个职能部分&#xff0c;让独立的环节自动运转起来。 npm和yarn体系特别庞大&#xff0c;在使用依赖时可能出现以下疑问 删除node_module…

数据结构之基本数据类型(Python)

前言 接下来我们将会先学习Python 的基本数据类型&#xff0c;以及堆、栈、链表、树和图等数据结构&#xff0c;这是学习算法的基础。套用行业内的一句话&#xff1a; 数据结构是算法的骨骼。 数据结构是一门庞大的学科&#xff0c;远不是一本书就可以讲清楚的。如果想更深入地…

安全跟我学|这些网络安全知识,请务必牢记

随着“互联网”时代的到来&#xff0c;人们的生活变得更加便利&#xff0c;但电信诈骗、信息泄露、网络谣言、恶意软件等也随之而来。面对网络这把双刃剑&#xff0c;如何绷紧思想“安全弦”&#xff0c;正确安全使用网络呢&#xff1f;带着这些疑问&#xff0c;让我们一起来学…

【不需要网络不需要显卡】本地部署GPT

【不需要网络/不需要显卡】本地部署GPT 大家好&#xff0c;我是老 J 我们都知道ChatGPT目前只有两种使用方式&#xff0c;一种是直接去官网访问&#xff0c;适合个人用户&#xff1b;另一种是API调用&#xff0c;适合企业或者网站使用。这两种方式的门槛都比较高&#xff0c;…

springboot105基于保信息学科平台系统设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的基于保信息学科平台系统设计与实现 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 …

PXE批量高效网络装机

总结 1实验流程只能抄老师&#xff0c;记忆浅 2排错能力几乎无 3 指令用的太死&#xff0c; 一 系统装机的三种引导方式 启动 操作 系统 1.硬盘 2.光驱&#xff08;u盘&#xff09; 3.网络启动 pxe 重装系统&#xff1f; 在已有操作系统 新到货了一台服务器&#xff…

常见的查找算法

前提&#xff1a;除了线性查找外&#xff0c;下面的其他查找算法适用于有序数组&#xff08;以从小到大为例&#xff09; 一、线性查找 /*** 这里若要查找重复出现的数&#xff0c;可以把索引放入到一个集合中* param arr* param value* return 如果没有找到&#xff0c;则返…

联合体中嵌套结构体,结构体未命名时,结构体成员变量的引用

参考文章&#xff1a;C语言 结构体 联合体 | 嵌套使用_联合体里面嵌套结构体-CSDN博客 如题&#xff0c;其实直接用 联合体名.结构体成员变量名 即可。 程序&#xff1a; #include <stdio.h>typedef unsigned int uint32_t; typedef unsigned char uint8_t;union b…

GNSS数据下载软件 -- 武汉大学 Fast软件(体验感极佳~)

目录 一、简介与下载地址 1.介绍 2.软件特点 3.下载地址 4.以github下载链接为例 二、下载方法(三种方法&#xff0c;以windows系统为例) 1.双击"Fast.exe"根据提示引导下载 2.手动输入"cmd"进入命令行界面&#xff0c;通过输入相关命令进行下载 …

el-date-picker如果超过限制跨度则提示

需求&#xff1a;实现日期时间选择组件跨度如果超过限制天数&#xff0c;点击查询则提示超过限制时间 封装一个方法&#xff0c;传入开始和结束时间以及限制天数&#xff0c;如果超过则返回false //计算时间跨度是否超过限制天数isTimeSpanWithinLimit(startTime, endTime, li…

Python编程之旅7:函数

欢迎来到第七篇《Python编程之旅》的博客&#xff01;在前面的几篇博客中&#xff0c;我们已经学习了Python的基本语法、数据类型、流程控制语句以及列表、元组和字典等内容。今天&#xff0c;我们将进一步探索Python编程的世界&#xff0c;重点关注函数。 函数 函数是一种可…

AIOps探索 | 应急处置中排障的降本增效方法探索

原作者&#xff1a;擎创科技 资深产品专家 布博士 前言 在事件管理及应急场景的场景下&#xff0c;一般会造成业务服务和技术服务故障&#xff08;如应用系统、微服务架构等不同的技术组件&#xff09;。为了实现对业务的影响分析、查看技术组件的相互依赖关系以及进行根因排…

WSL中Ubuntu出现过的问题!!!

1. 问题&#xff1a;在运行代码过程中突然掉线&#xff0c;然后自动连线后使用su登录root失败&#xff0c;并且sudo失效 ubuntuLAPTOP-3II6MIRG:/mnt/c/Windows/system32$ su Password: Ubuntu …

数组翻转(C++)

对于一副扑克牌&#xff0c;我们有多种不同的洗牌方式。一种方法是从中间某个位置分成两半&#xff0c;然后相交换&#xff0c;我们称之为移位&#xff08;shift&#xff09;。 比如原来的次序是 123456&#xff0c;从第 4 个位置交换&#xff0c;结果就是 561234。 这个方式其…

使用opencv把视频转换为灰色并且逐帧率转换为图片

功能介绍 使用opencv库把视频转换为灰色&#xff0c;并且逐帧率保存为图片到本地 启动结果 整体代码 import cv2 import osvc cv2.VideoCapture(test.mp4)if vc.isOpened():open, frame vc.read() else:open Falseos.makedirs("grayAll", exist_okTrue) i 0 wh…

冻结Prompt微调LM: T5 PET (a)

T5 paper: 2019.10 Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer Task: Everything Prompt: 前缀式人工prompt Model: Encoder-Decoder Take Away: 加入前缀Prompt&#xff0c;所有NLP任务都可以转化为文本生成任务 T5论文的初衷如…