导出文件,能够导出但是文件打不开

背景:

在项目开发中,对于列表的查询,而后会有导出功能,这里导出的是一个excell表格。实现了两种,1.导出的文件,命名是前端传输过去的;2.导出的文件,命名是根据后端返回的文件名获取的。

 //解码获取导出文件名

        const fileNames = res.headers['content-disposition']

        const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1])

//能够导出但是打不开,导出接口的网络请求要带上responseType: 'blob',

     //导出文件【get】

    exportCrewInfoFile(params) {

        return request.Get("/data/ferryShip/download?", params, {

            headers: {

                "Content-Type": "application/json",

            },

            responseType: 'blob',

        });

    },

    //导出文件【post】

    exportWarningFile(params) {

        return request.Post("/data/warningRecord/download", params, {

            headers: {

                "Content-Type": "application/json",

            },

            responseType: 'blob',

        });

    },

前端界面:

前端请求接口,axios发起网络请求:

axios封装:

import axios from "axios";
import useShoreBasedStore from "@/store";
import qs from 'qs';
import router from "@/router/index.js";
import { ElMessageBox } from "element-plus";let messageBoxVisible = false
export const BASEUrl = import.meta.env.VITE_USER_NODE_ENV === 'development' ? '/apiproxy/pa' : import.meta.env.VITE_API_URL + '/pa'
const request = axios.create({baseURL: BASEUrl,timeout: 3000 * 60,headers: { "Content-Type": "application/x-www-form-urlencoded" },
});/*** 请求拦截添加token* */
request.interceptors.request.use((config) => {const user = useShoreBasedStore();if (user.userInfo.token) {config.headers.Authorization = user.userInfo.token;}return config;
}, (error) => {return Promise.reject(error)
});const showMsg = () => {if (!messageBoxVisible) {messageBoxVisible = trueconst user = useShoreBasedStore()ElMessageBox.confirm('您的登录信息已过期,请重新登录!','温馨提示',{confirmButtonText: '确认',cancelButtonText: '取消',type: 'warning'}).then(() => {user.loginOut()router.push({ name: 'login' })}).catch(() => {}).finally(() => {messageBoxVisible = false})}
}request.interceptors.response.use((response) => {const data = response.dataif (data.status === 401 || data.code === 401) {showMsg()} else {return response}
}, (error) => {if (error.response.data.code === 401) {showMsg()} else {return Promise.reject(error)}
})// 定义get方法
request.Get = function (url, params, config) {if (params) {return request.get(url + qs.stringify(params), config);}return request.get(url, config);
};// 定义post方式
request.Post = function (url, params, config) {if (params) {return request.post(url, params, config);}return request.post(url, config);
};export default request;

接口:

import request from "../utils/request.js";const fileApi = {// 上传文件uploadFile(params) {return request.Post("/data/file/upload", params, {headers: {"Content-Type": "multipart/form-data",},});},// 删除文件deleteFile(params) {return request.Post("/data/file/delete", params, {headers: {"Content-Type": "application/json",},});},//导出文件【get】exportFerryPortFile(params) {return request.Get("/data/ferryPort/download?", params, {headers: {"Content-Type": "application/json",},responseType: 'blob',});},//导出文件【post】exportWarningFile(params) {return request.Post("/data/warningRecord/download", params, {headers: {"Content-Type": "application/json",},responseType: 'blob',});},
}
export default fileApi;

导出封装的方法: 

/**** @param {*} fileContent 文件本体* @param {*} _fileName 自定义文件名*/
export const exportFileUtil = (fileContent, _fileName) => {const content = fileContent;const blob = new Blob([content], {type: fileContent.type || "application/octet-stream; charset=utf-8",});const fileName = _fileName;if ("download" in document.createElement("a")) {//非IE下载const a = document.createElement("a"); //创建一个a标签a.download = fileName; //指定文件名称a.style.display = "none"; //页面隐藏a.href = URL.createObjectURL(blob); // href用于下载地址document.body.appendChild(a); //插到页面上a.click(); //通过点击触发URL.revokeObjectURL(a.href); //释放URL 对象document.body.removeChild(a); //删掉a标签} else {//IE10 + 下载navigator.msSaveBlob(blob, fileName);}
};
/*** * @param {*} res 接口返回的文件流*/
export const dowloadFileUrl = (res) => {const fileNames = res.headers['content-disposition']if (fileNames) {//解码const fileName = decodeURIComponent(fileNames.match(/=(.*)$/)[1])// 处理返回的文件流const content = res.dataconst blob = new Blob([content], {type: res.data.type||"application/vnd.ms-excel"});if ('download' in document.createElement('a')) {//非IE下载const a = document.createElement('a') //创建一个a标签a.download = fileName //指定文件名称a.style.display = 'none' //页面隐藏a.href = URL.createObjectURL(blob) // href用于下载地址document.body.appendChild(a) //插到页面上a.click() //通过点击触发URL.revokeObjectURL(a.href) //释放URL 对象document.body.removeChild(a) //删掉a标签} else {//IE10 + 下载navigator.msSaveBlob(blob, fileName)}}
}

使用导出的方法:

//只是举例,根据实际进行调整
const exportExcel = () => {const search = searchForm.value.submitData();const params = {...search,};api.fileApi.exportCrewInfoFile(params).then((res) => {if (res.status === 200) {exportFileUtil(res.data, "渡口管理导出文件.xlsx");dowloadFileUrl(res)}}).finally((err) => {console.log(err);});
};

写到这儿,就实现了导出功能。。。下面的是导出接口的详细解释: 

 

一、导出文件使用get请求

(1)、导出文件,get请求里面传参有数组等复杂数据结构

前端界面:

上图可以看见post查询接口可以返回4条数据,那么导出功能以同样的参数也应该导出4条数据的excell。

导出传参:

结果:

导出文件但是打不开,原因可能是:传参的问题;接口返回的数据有问题。 

能够导出,不能打开文件。

 经过排查,是前端请求有问题,如下图:

能够导出,并且能够打开的。get请求的响应体和请求体的结构。如下:请求传参带上,responseType: 'blob',【必须带上】

二、导出文件使用post请求 

前端界面:

导出传参:

总结:

导出功能,不管前端使用的是get或者post请求,都需要后端对接受到的传参进行识别,进而返回对应的响应体。 

前端请求一定要带上responseType: 'blob',

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

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

相关文章

ISP各模块功能介绍

--------声明,本文为转载整理------- ISP各个模块功能介绍: 各模块前后效果对比: 黑电平补偿(BLC) 在理想情况下,没有光照射的像素点其响应值应为0。但是,由于杂质、受热等其它原因的影响&…

dockerfile实现lnmp

dockerfile实现lnmp 自定义镜像实现整个架构 (基础镜像centos7) nginx cd /opt mkdir nginx mysql php vim Dockerfile docker network create --subnet172.111.0.0/16 mynetwork #创建自定义网段 docker run -itd --name nginx -p 80:80 --cpu-quota 20000 -m 512m -v /op…

DeepSeek-V3技术报告

摘要 https://arxiv.org/pdf/2412.19437v1 我们介绍DeepSeek-V3,这是一个强大的混合专家(MoE)语言模型,具有6710亿个总参数,每个token激活37亿个参数。为了实现高效推理和经济实惠的训练,DeepSeek-V3采用了…

【spring mvc】文件上传、下载

文件上传,存储至本地目录中 一、代码1、工具类(敏感后缀过滤)2、文件上传,存储至本地3、文件下载 二、效果演示1、上传1.1、postMan 请求1.2、上传效果 2、下载2.1、下载效果 一、代码 1、工具类(敏感后缀过滤&#x…

CryptoMamba:利用状态空间模型实现精确的比特币价格预测

“CryptoMamba: Leveraging State Space Models for Accurate Bitcoin Price Prediction” 论文地址:https://arxiv.org/pdf/2501.01010 Github地址:https://github.com/MShahabSepehri/CryptoMamba 摘要 预测比特币价格由于市场的高波动性和复杂的非线…

dockerfile2.0

dockerfile实现lnmp nginx centos7 mysql centos7 php centos7 自定义镜像来实现整个架构 cd /opt mkdir nginx mysql php cd nginx 拖入nginx和wordpress vim Dockerfile vim nginx.conf ↓ worker_processes 1; events {worker_connections 1024; } http {include …

C#类型转换

C#是静态类型的语言,变量一旦声明就无法重新声明或者存储其他类型的数据,除非进行类型转换。本章的主要任务就是学习类型转换的知识。类型转换有显式的,也有隐式的。所谓显式,就是我们必须明确地告知编译器,我们要把变…

智能物流升级利器——SAIL-RK3576核心板AI边缘计算网关设计方案(一)

近年来,随着物流行业智能化和自动化水平不断提升,数据的实时处理与智能决策成为推动物流运输、仓储管理和配送优化的重要手段。传统的集中式云平台虽然具备强大计算能力,但高延迟和带宽限制往往制约了物流现场的即时响应。为此,我…

【算法篇】前缀和

🔥个人主页:Quitecoder 🔥专栏:算法笔记仓 前缀和是一种常用于处理数组区间求和问题的技巧。它可以用来减少重复计算,使得多次查询区间和的时间复杂度从 O(n) 降低到 O(1) 目录 1. 一维模版2. 二维模版3. 除自身以外数…

第R4周:LSTM-火灾温度预测

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 文章目录 一、代码流程1、导入包,设置GPU2、导入数据3、数据集可视化4、数据集预处理5、设置X,y6、划分数据集7、构建模型8、定义训练函…

机组存储系统

局部性 理论 程序执行,会不均匀访问主存,有些被频繁访问,有些很少被访问 时间局部性 被用到指令,不久可能又被用到 产生原因是大量循环操作 空间局部性 某个数据和指令被使用,附近数据也可能使用 主要原因是顺序存…

Windows图形界面(GUI)-QT-C/C++ - Qt图形绘制详解

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 Qt绘图基础 QPainter概述 基本工作流程 绘图事件系统 paintEvent事件 重绘机制 文字绘制技术 基本文字绘制 ​编辑 高级文字效果 基本图形绘制 线条绘制 ​编辑 形状绘制 …

mapbox进阶,添加绘图控件

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图控…

client-go 的 QPS 和 Burst 限速

1. 什么是 QPS 和 Burst ? 在 kubernetes client-go 中,QPS 和 Burst 是用于控制客户端与 Kubernetes API 交互速率的两个关键参数: QPS (Queries Per Second) 定义:表示每秒允许发送的请求数量,即限速器的平滑速率…

WeakAuras NES Script(lua)

WeakAuras NES Script 修星脚本字符串 脚本1:NES !WA:2!TMZFWXX1zDxVAs4siiRKiBN4eV(sTRKZ5Z6opYbhQQSoPtsxr(K8ENSJtS50(J3D7wV3UBF7E6hgmKOXdjKsgAvZFaPTtte0mD60XdCmmecDMKruyykDcplAZiGPfWtSsag6myGuOuq89EVDV9wPvKeGBM7U99EFVVVV33VFFB8Z2TJ8azYMlZj7Ur3QDR(…

【make】makefile 函数全解

目录 makefile简介函数全解介绍相关链接字符串处理函数subst 函数—字符串替换patsubst 函数 — 模式字符串替换strip 函数 — 去空格findstring 函数 — 查找字符串filter 函数 — 过滤器filter-out 函数 — 过滤器sort 函数 — 排序word 函数 — 取单词wordlist函数 — 取一串…

Android 15应用适配指南:所有应用的行为变更

Android系统版本适配,一直是影响App上架Google Play非常重要的因素。 当前Google Play政策规定 新应用和应用更新 必须以 Android 14(API 级别 34)为目标平台,才能提交到Google Play。现有应用 必须以 Android 13(AP…

Java Agent(三)、ASM 操作字节码入门

目录 1、前言 2、什么是ASM? 2.1、工作流程 2.2、ASM集合核心API 2.1.1、ClassReader 2.1.2、ClassWriter 2.1.3、 ClassVisitor 2.1.4、MethodVisitor 2.1.5、 FieldVisitor 2.1.6、Opcodes 3、简单示例 3.1、maven依赖 3.2、hello world 3.3、执行结…

MySQL数据库(SQL分类)

SQL分类 分类全称解释DDLData Definition Language数据定义语言,用来定义数据库对象(数据库,表,字段)DMLData Manipulation Language数据操作语言,用来对数据库表中的数据进行增删改DQLData Query Languag…

[微服务]redis数据结构

介绍 我们常用的Redis数据类型有5种,分别是: StringListSetSortedSetHash 还有一些高级数据类型,比如Bitmap、HyperLogLog、GEO等,其底层都是基于上述5种基本数据类型。因此在Redis的源码中,其实只有5种数据类型。 …