Files
vue3-element-admin/src/utils/download.ts
2026-06-12 21:21:49 +08:00

74 lines
2.0 KiB
TypeScript

/**
* 文件下载工具函数
*/
/**
* 从响应头中提取文件名
* @param contentDisposition Content-Disposition 响应头
* @returns 解码后的文件名
*/
function extractFileName(contentDisposition: string): string {
if (!contentDisposition) {
return `download_${Date.now()}`;
}
// 尝试从 filename*=UTF-8'' 格式中提取
const filenameRegex = /filename\*=UTF-8''(.+)/;
const matches = filenameRegex.exec(contentDisposition);
if (matches && matches[1]) {
return decodeURIComponent(matches[1]);
}
// 尝试从 filename= 格式中提取
const fallbackRegex = /filename=([^;]+)/;
const fallbackMatches = fallbackRegex.exec(contentDisposition);
if (fallbackMatches && fallbackMatches[1]) {
return decodeURI(fallbackMatches[1].replace(/"/g, ""));
}
return `download_${Date.now()}`;
}
/**
* 下载文件
* @param response Axios 响应对象
* @param customFileName 自定义文件名(可选)
*
* @example
* ```ts
* // 基础用法
* const response = await UserAPI.export(queryParams);
* downloadFile(response);
*
* // 自定义文件名
* downloadFile(response, "用户列表.xlsx");
* ```
*/
export function downloadFile(response: { data: any; headers: Record<string, string> }, customFileName?: string): void {
try {
const fileData = response.data;
const contentDisposition = response.headers["content-disposition"];
const fileName = customFileName || extractFileName(contentDisposition);
// 创建 Blob 对象
const blob = new Blob([fileData]);
// 创建下载链接
const downloadUrl = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = downloadUrl;
link.download = fileName;
// 触发下载
document.body.appendChild(link);
link.click();
// 清理
document.body.removeChild(link);
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error("文件下载失败:", error);
throw error;
}
}