接到这种需求时,看到“下载”、“导出”字样时,脑海里首先浮现的就是需要借助 a 标签 实现下载或者导出功能,即
// 动态创建a
const a = document.createElement('a');
a.href = url; // url 表示文件链接
a.download = fileName + '.xlsx'; // 以导出excel为例,即后缀是.xlsx,fileName表示文件名称
a.click();
那么,接下来就是思考上边那个变量 url 如何构建,这个是什么?其实就是我们需要下载出的文件。
结合后端接口返回的是一个文件流,即Blob对象类型,那么我们可以将这个“”流“”转换成被下载文件的一个内存URL,这时候就要用到 createObjectURL 这个方法了。以导出excel为例,完整代码就是:
const contentType =
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; // 文件流类型
const blob = new Blob([data], { type: contentType }); // data表示后端返回的文件流数据
const url = window.URL.createObjectURL(blob);
// 动态创建a 进行下载
const a = document.createElement('a');
a.href = url; // url 表示文件链接
a.download = fileName + '.xlsx'; // 以导出excel为例,即后缀是.xlsx,fileName表示文件名称
a.click();
window.URL.revokeObjectURL(url);
从内存管理角度来说:
在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。
浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。
如果要下载其他类型的文件,可根据下方表格替换相应的字段值
后缀名 | 文件流类型 |
---|---|
.doc | application/msword |
.docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.xls | application/vnd.ms-excel |
.xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.ppt | application/vnd.ms-powerpoint |
.pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation |
application/pdf | |
.zip | application/zip |
.png | image/png |
bmp | image/bmp |
.avi | video/x-msvideo |
.mpeg | video/mpeg |
.mpg | video/mpeg |
.movie | video/x-sgi-movie |
.mp3 | audio/mpeg |
.wav | audio/x-wav |
.txt | text/plain |
至此,下载/导出一个文件的功能就实现了!