欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 导出文件,能够导出但是文件打不开

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

2025/11/19 6:04:32 来源:https://blog.csdn.net/weixin_45024453/article/details/145072243  浏览:    关键词:导出文件,能够导出但是文件打不开

背景:

在项目开发中,对于列表的查询,而后会有导出功能,这里导出的是一个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',

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词