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
点到为止