vue+.netCore 下载导出文件
一、 下载
后端代码
/// <summary> /// 异步导出投诉报告 /// </summary> /// <param name="exportParams">投诉报告查询参数</param> /// <returns>文件流响应</returns> [Route("/qms/complain/export/report")] [HttpPost] [Core.Filter.IgnoreActionLog] // 忽略日志记录 public async Task<IActionResult> ExportComplaintReportAsync([FromBody] ComplaintReportDto exportParams) { // 获取文件流和文件名 var complaintReportService = new ComplaintReportService(GetUserDBConnection()); var userName = GetUserName(); var (fileStream, fileName) = await complaintReportService.ExportComplaintReportAsync(exportParams, userName); // 重置文件流位置 fileStream.Position = 0; // 允许前端获取 Content-Disposition 响应头 Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition"); // 返回文件流 return File(fileStream, "application/octet-stream", fileName); }
前端代码
/**
* 通用文件下载方法
*
* @param {string} url 请求地址
* @param {object} params 请求参数
* @param {object} options 配置选项,可选(method, headers, responseType)
* @returns {Promise} 返回完整响应体(包含文件流)
*
* 示例:
* downloadFile('/api/download', { id: 1 })
* .then(response => {
* // 处理下载的文件流
* })
*/
export function downloadFile(url, params, options = {}) {
const {
method = 'POST',
headers = {
'Content-Type': 'application/json'
},
responseType = 'blob',
} = options;
const token = getAccessToken() || getToken();
// 创建独立的axios实例,避免全局拦截器干扰
const instance = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 300000,
headers: {
...headers,
...(token ? { 'Authorization': 'Bearer ' + token } : {})
},
responseType,
});
const config = {
url,
method,
};
if (method.toUpperCase() === 'GET') {
config.params = params;
} else {
config.data = params;
}
return instance.request(config)
.then(response => {
return response; // 返回完整响应体,包含 headers、status、data
})
.catch(error => {
return Promise.reject(error);
});
}
调用下载
/**
* 下载文件
* @param {Object} response 响应对象
*/
downloadFile(response) {
const contentDisposition = response.headers['content-disposition'] || '';
const filenameRegex = /filename\*=UTF-8''([^;]+)/;
const match = filenameRegex.exec(contentDisposition);
if (!match) {
console.error('未获取到文件名,下载中止');
return;
}
const filename = decodeURIComponent(match[1]);
const blob = response.data;
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url);
document.body.removeChild(link);
},
/** * 通过POST请求获取文件 * * 使用POST方法向文件接口提交查询参数,获取文件流(适用于参数较多或复杂的场景) * * @param {Object} queryData - POST请求的查询参数对象 * @returns {Promise<Blob>} 返回文件流的Promise对象,resolved值为Blob类型 * * 示例: * getFileByPost({ id: '123', type: 'report' }) * .then(response => { * // 处理文件流(预览或下载) * handleFileResponse(response); * }) */ export function getFileByPost(queryData) { // 显式指定method为POST,与函数功能保持一致 return downloadFile('/wms/file/getfile', queryData, { method: 'POST' }); } /** * 下载文件(GET方式) * * 使用GET方法向文件接口传递查询参数,获取文件流 * 适用于参数简单、长度有限的场景 * * @param {Object} queryParams - GET请求的查询参数对象(会转为URL查询字符串) * @returns {Promise<Blob>} 返回文件流的Promise对象 * * 示例: * getFileByGet({ fileId: '123', type: 'preview' }) * .then(response => { * // 处理文件流(预览或下载) * }) */ export function getFileByGet(queryParams) { // 显式指定method为GET,参数会自动作为URL查询参数 return downloadFile('/wms/file/getfile', queryParams, { method: 'GET' }); }
接口调用
https://blog.51cto.com/u_16213413/12422025
https://blog.csdn.net/weixin_43118088/article/details/128852084
点到为止

浙公网安备 33010602011771号