背景
最近有一个独自和批量下载 pdf 的文件的需要。独自下载首先想到的是用 a 标签 download 属性间接下载。实际中发现,浏览器会默认关上pdf文件,而不是间接下载。批量下载须要压缩,这一步也须要在前端实现。
这里记录下我的实现形式。实用于绝大部分文件。
筹备工作
这里用到了两个 npm 包:
- jszip
- file-saver
jszip
用于压缩。file-saver
用于在前端保留文件。
npm install file-saver jszip --save
装置好之后,先实现独自下载。
独自下载
独自下载 pdf,只用 file-saver 就能够了。
import { saveAs } from 'file-saver';
function save() {
saveAs(blob, filename);
}
saveAs 办法有两个参数,第二个参数是下载的文件名,第一个参数就比拟难获取了,是一个 Blob
对象
什么是 Blob?传送门
当初的状况是接口返回了pdf的URL,而后我要用这个url获取对应PDF的blob。
怎么做?当然是 ajax
。
ajax 获取blob
间接贴上代码:
const getPdfBlob = (url: string) => {
return new Promise((resolve, reject)=> {
let xhr = new XMLHttpRequest()
xhr.open('get', url+'?t='+Math.random(), true);
xhr.setRequestHeader('Content-Type', `application/pdf`);
xhr.responseType = 'blob';
xhr.onload = function () {
if (this.status == 200) {
//承受二进制文件流
var blob = this.response;
resolve(blob);
}
}
xhr.send();
})
}
首先,写一个原生的 XMLHttpRequest
,办法为 get,url 中的 t 参数是为了阻止缓存。而后设置 responseType
为 blob,最初承受回来的就是 blob 数据。
为了前面批量应用,getPdfBlob
函数外部用 promise 包了一下。
应用办法:
getPdfBlob(url).then(blob => {
saveAs(blob, filename);// 拿到 blob 并下载 pdf
})
独自下载搞定!
批量下载
首先,批量下载要压缩成zip包之后下载,所以要用到 jszip
。
这里写了一个将批量文件压缩为一个zip的办法:
import JSZip from 'jszip'
import { saveAs } from 'file-saver';
getMultiZip(blobs)=> {
var zip = new JSZip();
blobs.forEach(blob=> {
// 增加要压缩的pdf
zip.file('单个pdf文件名.pdf', blob, { binary:true });
})
zip.generateAsync({type:'blob'}).then(function(content) {
//生成zip并保留
saveAs(content, '批量pdf文件名.zip');
});
}
有了这个办法之后,接下来批量获取 blob。
独自下载须要发动一个 ajax,批量下载,就要每个 URL 都发动 ajax。
因为后面的 getPdfBlob
包装了promise,所以批量获取就能够这样写:
Promise.all(
pdfUrlList.map(url=> getPdfBlob(url))
).then(res=> {
// res构造:[blob, blob, blob, ...]
getMultiZip(res)
})
这里用 Promise.all
的益处是能够并行发动申请,等最初一个申请完结后拿到所有的 blob,比循环执行 ajax 高效的多。
批量下载搞定!
发表回复