☰
vue 实现 word、ppt、excel、图片、PDF、视频、音频等格式的文件下载,以及uniapp中文件包(文件流)的下载处理
2026/10/10 1:15:17 网站建设 项目流程

方法一:a标签

1、后台返回的url地址

// 下载 const downLoad = (url: string, name: string,type:string) => { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'arraybuffer'; // 返回类型blob xhr.onload = function () { if (xhr.readyState === 4 && xhr.status === 200) { let blob = this.response; // 转换一个blob链接 // 注: URL.createObjectURL() 静态方法会创建一个 DOMString(DOMString 是一个UTF-16字符串), // 其中包含一个表示参数中给出的对象的URL。这个URL的生命周期和创建它的窗口中的document绑定 let downLoadUrl ='' if (type==='视频'){ downLoadUrl = window.URL.createObjectURL(new Blob([blob], { type: 'video/mp4' })); } else if (type === '图片' || type === '文件'){ downLoadUrl = url } // 视频的type是video/mp4,图片是image/jpeg // 01.创建a标签 let a = document.createElement('a'); // 02.给a标签的属性download设定名称 a.download = name; // 03.设置下载的文件名 a.href = downLoadUrl; // 04.对a标签做一个隐藏处理 a.style.display = 'none'; // 05.向文档中添加a标签 document.body.appendChild(a); // 06.启动点击事件 a.click(); // 07.下载完毕删除此标签 a.remove(); }; }; xhr.send() }

2、后台返回文件流,指定了文件类型

export function getExportJobQuest(data: any) { return request({ url: '', method: 'post', responseType: 'blob', data }) } // 点击导出按钮 const downQuestObject = async () => { const res = await getExportJobQuest(selectQuestGroupIds.value) downloadFile(res,currJob.value.name) } const downloadFile = (filestream:any,fileName:string) => { // filestream: 返回的文件流 fileName: 设置下载的文件名称 const blob = new Blob([filestream],{type:'application/vnd.openxmlformats-officedocument.wordprocessingml.document'||'application/msword'}); const a = document.createElement('a'); const href = window.URL.createObjectURL(blob); // 创建下载连接 a.href = href; a.download = decodeURI(fileName); document.body.appendChild(a); a.click(); document.body.removeChild(a); // 下载完移除元素 window.URL.revokeObjectURL(href); // 释放掉blob对象 }

3、后台返回文件流,没返回文件类型 application/octet-stream

// 文件下载 export const downFileApi = (id:number) => { let token = storage.getItem(constant.CONFIG_TOKEN) return axios.get( import.meta.env.VITE_BASE_URL_API + `/api/user/userresourcemanagement/downfile?resourceId=${id}`, { headers: { Authorization: `Bearer ${token}`, }, responseType: "arraybuffer" } ); } // 下载按钮 const downDatas = async (item: any) => { const res = await downFileApi(item.id) downloadFile(res, () => {}) } export function downloadFile(res: any, fun: Function) { let filename = res.headers["content-disposition"] .split(";")[2] .split("filename*=UTF-8''")[1]; console.log(66,filename) //创建一个隐藏的a链接 const link = document.createElement("a"); let blob = new Blob([res.data], { type: res.headers["content-type"] }); //文件流处理 link.style.display = "none"; //去除a标签的样式 //设置连接 link.href = window.URL.createObjectURL(blob); link.download = window.decodeURI(filename); document.body.appendChild(link); //模拟点击事件 link.click(); //移除创建的a标签 document.body.removeChild(link); window.URL.revokeObjectURL(link.href); fun(false); }

方法二:阿里云——获取文件的下载URL

地址:预览或下载文件 - 对象存储 OSS - 阿里云

1、安装 ali-oss
cnpm install --save ali-oss
2、页面调用,client 中相关的属性需要自己去配置(后端提供接口即可)
(1)使用 client.signatureUrl 获取下载路径,并通过new XMLHttpRequest() 获取下载进度
const downLoad =async (item:any) => { let res:TResponse<TDownType>= await getAliossSetting() let {Code,Data}=res if(Code===200){ const OSS = require('ali-oss'); person.client = new OSS({ // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。 region: Data.RegionId, // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。 accessKeyId: Data.AccessKeyID, accessKeySecret: Data.AccessKeySecret, // 从STS服务获取的安全令牌(SecurityToken)。 // stsToken: 'yoursecurityToken', // 填写Bucket名称。 bucket: Data.Bucket, }); } // 配置响应头实现通过URL访问时自动下载文件,并设置下载后的文件名。 var ext = item.Url.split('.')[item.Url.split('.').length - 1] const filename = item.Name+'.'+ext const response = { 'content-disposition': `attachment; filename=${encodeURIComponent(filename)}` } // item.OldUrl有前面http://lujin.com拼接的地址,则需要处理掉 // item.OldUrl: 'App.Live/教学部/uploads/图片/2022-08-23/e014dca2f0ff4f1e90ac931f32018140.png' // 填写Object完整路径。Object完整路径中不能包含Bucket名称。 const URL = person.client.signatureUrl(item.OldUrl, { response }); // 下载1:只下载不获取下载进度 window.location.href=URL // 下载2:下载获取进度 let xhr = new XMLHttpRequest(); xhr.open('GET', result, true); xhr.responseType = 'blob'; // 根据需要设置响应类型 xhr.onprogress = function (event) { // `event.loaded` 是已下载的字节数,`event.total` 是文件的总字节数 state.downloadProgress = ((event.loaded / event.total) * 100).toFixed(0); }; xhr.onload = function () { if (xhr.status === 200) { // 处理下载完成的文件,例如保存为 Blob 或转换为其他格式 var blob = xhr.response; console.log('blob', blob) let downloadElement = document.createElement('a') let href = window.URL.createObjectURL(blob) //创建下载的链接 downloadElement.href = href downloadElement.download = filename //下载后文件名 document.body.appendChild(downloadElement) downloadElement.click() //点击下载 document.body.removeChild(downloadElement) //下载完成移除元素 window.URL.revokeObjectURL(href) //释放掉blob对象 // ...后续处理 blob 数据 } else { console.error('Download failed with status ' + xhr.status); } }; xhr.onerror = function () { console.error('XMLHttpRequest error'); }; xhr.send(); }
(2)使用 client.get 获取单个文件下载路径
import OSS from 'ali-oss' //下载资源 const onDownFile = async (item: any, fun: any) => { let client = null try { const { Code, Data } = await getAliossSetting() if (Code === 200) { // const OSS = require('ali-oss'); client = new OSS({ // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。 region: Data.RegionId, // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。 accessKeyId: Data.AccessKeyID, accessKeySecret: Data.AccessKeySecret, // 从STS服务获取的安全令牌(SecurityToken)。 stsToken: Data.AliyunOSSToken, // 填写Bucket名称。 bucket: Data.Bucket }); } // 下载文件的逻辑 // 处理filename组成:资料寒假周二(1.21)《Subject Clause》-白亭.pdf const filename = item.Name // 处理Url组成:App.Live/uploads/文件/2025-01-17/7731d2adc41e4abea45fa8cb730884ba.pdf let splitName = 'App.Live' const Url = splitName + row.Url.split(splitName)[1] + '.' + row.Extension // 生成签名URL client.get(Url, { progress: function (p: any) { console.log('Progress: ' + p * 100); } }).then(function (r: any) { if (r.content.length > 0) { const newBlob = new Blob([r.content], { type: r.res.headers['content-type'] }); const link = document.createElement('a') link.href = window.URL.createObjectURL(newBlob) link.download = filename link.click() window.URL.revokeObjectURL(link.href) fun(false) } else { console.log('错误码', r.res.status) console.log('没有符合条件的下载项') } }).catch(function (err: any) { console.error('Error downloading file:', err); fun(false) }); } catch (error) { console.error('Error downloading file:', error); fun(false) } }
(3)使用 client.get 获取多个文件下载路径(以.zip下载),并获取下载进度

A、安装插件 jszip file-saver

cnpm install --save jszip file-saver

B、文件包下载

import OSS from 'ali-oss' import JSZip from 'jszip'; import { saveAs } from 'file-saver'; // 如果后台返回的包结构不是以下,则需要先处理成以下结构再操作 const KeyVals = [ { FileName: "资料寒假周二(1.21)《Subject Clause》-白亭.pdf", FileUrl: "App.Live/uploads/文件/2025-01-17/7731d2adc41e4abea45fa8cb730884ba.pdf", MaterialType: "文件" }, { FileName: "第一章_函数_第三讲:抽象函数.pdf", FileUrl: "App.Live/uploads/文件/2025-01-21/945bb6b5c7d349af9814b17bfdb19f52.pdf", MaterialType: "文件" }, { FileName: "一诊讲评 伍.pptx", FileUrl: "App.Live/uploads/文件/2025-01-20/218197663878479e9ac64f57ebf9d0e2.pptx", MaterialType: "文件" }, { FileName: "历史期末评讲.pptx", FileUrl: "App.Live/uploads/文件/2025-01-17/c555be08a1434d8e98b2d1f1ac5772cb.pptx", MaterialType: "文件" }, { FileName: "资料寒假周日(1.19)《Finite Verb》.pdf", FileUrl: "App.Live/uploads/文件/2025-01-17/0aa79ed3db7e431d8064a02175898be4.pdf", MaterialType: "文件" }, { FileName: "高一上2027届第二十周历史教学规划.docx", FileUrl: "App.Live/uploads/文件/2025-01-14/81e8462a6f7d4075ad6a5c4c824a9b5b.docx", MaterialType: "文件" }, { FileName: "周一(1.13)读后续写 校园生活 专题PPT.pptx", FileUrl: "App.Live/uploads/文件/2025-01-14/3230a390016f49299341a3f7dec8b46d.pptx", MaterialType: "文件" }, { FileName: "1.8作业.docx", FileUrl: "App.Live/uploads/文件/2025-01-09/a2922aa4e0e64071a53d439dc1af902f.docx", MaterialType: "文件" }, { FileName: "新外研必修二 Unit 2 Let's celebrate! developing idea.docx", FileUrl: "App.Live/uploads/文件/2024-12-23/f6815e6ece9b47d887ec111f107dd640.docx", MaterialType: "文件" } ] //下载资源包 const onResourceDownload = async (row: any, fun: any) => { let client: any = null try { const { Code, Data } = await getAliossSetting() if (Code === 200) { // const OSS = require('ali-oss'); client = new OSS({ // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。 region: Data.RegionId, // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。 accessKeyId: Data.AccessKeyID, accessKeySecret: Data.AccessKeySecret, // 从STS服务获取的安全令牌(SecurityToken)。 stsToken: Data.AliyunOSSToken, // 填写Bucket名称。 bucket: Data.Bucket }); } // 下载文件包的逻辑 const zip = new JSZip(); const totalFiles = KeyVals.length; let downloadedFiles = 0; let totalBytes = 0; let downloadedBytes = 0; // 获取所有文件的总大小 for (const key of KeyVals) { const result = await client.head(key.FileUrl); totalBytes += Number(result.res.headers['content-length']); } const promises: Promise<void>[] = []; for (const key of KeyVals) { const promise = new Promise<void>(async (resolve, reject) => { const xhr: any = new XMLHttpRequest(); xhr.open('GET', await client.signatureUrl(key.FileUrl), true); xhr.responseType = 'blob'; xhr.previousLoaded = 0; xhr.onprogress = (event: any) => { if (event.lengthComputable) { downloadedBytes += event.loaded - (xhr.previousLoaded || 0); xhr.previousLoaded = event.loaded; // 获取下载过程中的进度数据 state.downloadProgress = ((downloadedBytes / totalBytes) * 100).toFixed(0); } }; xhr.onload = () => { if (xhr.status === 200) { zip.file(key.FileName, xhr.response); downloadedFiles++; if (downloadedFiles === totalFiles) { zip.generateAsync({ type: 'blob' }).then((content: any) => { saveAs(content, row.Title + '.zip'); fun(false); state.isDowning = false }).catch((error) => { console.error('Error creating zip file:', error); fun(false); state.isDowning = false }); } resolve(); } else { console.error('Download failed with status ' + xhr.status); reject(new Error(`Download failed with status ${xhr.status}`)); } }; xhr.send(); }); promises.push(promise); } Promise.all(promises).catch((error) => { console.error('Error downloading files:', error); fun(false); state.isDowning = false }); } catch (error) { fun(false); state.isDowning = false } }
3、哪里需要哪里调用
// 图片下载 const dowmClick=(item:any)=>{ downLoad(item) }

注:其中在uniapp调用时,需将const OSS = require('ali-oss'); 换成 import OSS from 'ali-oss' 的引入方式

方法三:window.location.href 或 window.open

window.location.href = url 或 window.open(url)

方法四:文件包的下载处理

1、在Uniapp中 进行POST请求 下载文件流,uni.request 中 responseType 默认是 “ text” ,请求时会将 “ 流格式 ” 处理成 “ 字符串 ”,所以下载的包文件格式是错的,会导致乱码。因此使用uni.request 设置responseType 为 “ arraybuffer ”即可

export const Request=(options)=>{ return new Promise((resolve, reject) => { const token = uni.getStorageSync('token'); uni.request({ url: config.host + options.url, //接口地址:前缀+方法中传入的地址 method: options.method || 'GET', //请求方法:传入的方法或者默认是“GET” data: options.data || {}, //传递参数:传入的参数或者默认传递空集合 header: { 'Authorization':`Bearer ${token?token:''}`, 'Content-Type':'application/json;charset=utf-8', }, responseType:options.responseType || 'json', // 一定要设置为二进制的模式 success: (res) => { resolve(res) }, fail: (err) => { uni.showToast({ title: '请求失败,请刷新', duration: 2000, icon: 'none' }); reject(err) } }) }) }

2、接口调用

// 资料库下载 export const getDownFile = (param) => { return Request({ url: '​', // 接口地址 method: 'POST', responseType: 'arraybuffer', data:param }) }

3、页面中使用该接口

// 资料库下载 let GetDownFile = (item : any) => { // 上传参数 let obj = { FileName: person.FileName, KeyVals: person.KeyVals, ResourcesId: ..... } getDownFile(obj).then((res : any) => { let filename = res.header['content-disposition'].split(';')[2].split("filename*=UTF-8''")[1]; //创建一个隐藏的a链接 const link = document.createElement("a"); console.log(res.header['content-type']) let blob = new Blob([res.data], {type: res.header['content-type']}); //文件流处理 link.style.display = "none"; //去除a标签的样式 //设置连接 link.href = window.URL.createObjectURL(blob); link.download = window.decodeURI(filename); document.body.appendChild(link); //模拟点击事件 link.click(); //移除创建的a标签 document.body.removeChild(link); window.URL.revokeObjectURL(link.href); }) }

希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询