纯前端如何实现批量下载功能呢?
***需求:***在不依赖后端的情况下,前端需要独立实现批量下载,且下载的文件需统一放在一个文件夹中并压缩
插件:
html2canvas可以实现截图功能
JsPDF 可以将文件生成pdf
JSZip 可以压缩文件
FileSaver 保存文件到本地
代码如下:
javascript
<template>
<div>
<van-button @click="zipPdf">批量下载</van-button>
<div
v-for="(item, index) in pdfList"
:key="index"
id="downPdf"
style="margin-bottom: 50px"
>
标题{{ index }}
<div v-for="keys in 50" :key="keys">内容{{ keys }}</div>
</div>
</div>
</template>
javascript
<script>
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
import JSZip from 'jszip';
import FileSaver from 'file-saver';
export default {
name: 'zipPDF',
data() {
return {
isShow: false,
planName: '测试',
pdfList: [
{
taskId: '001',
taskName: '测试一',
num: '1',
},
{
taskId: '002',
taskName: '测试二',
num: '2',
},
],
};
},
methods: {
htmlToPDF() {
this.zipPdf();
},
//下载
async zipPdf() {
let allRefList = [];
for (let index = 0; index < this.pdfList.length; index++) {
let downPdfListRef = document.getElementById('downPdf');
let title =
this.pdfList[index].taskId + '-' + this.pdfList[index].taskName;
const p = await this.getPdf(downPdfListRef, title);
allRefList.push(p);
console.log('现在生成第' + (index + 1) + '份pdf页面了');
if (index === this.pdfList.length - 1) {
this.zipChange(allRefList);
}
}
},
//转pdf
getPdf(el, pdfName) {
return new Promise((resolve) => {
html2Canvas(el, {
allowTaint: true,
scale: 1, //处理模糊问题
useCORS: true, //开启跨域,这个是必须的
}).then(function (canvas) {
//需要异步处理
setTimeout(() => {
let pdf = new JsPDF('p', 'mm', 'a4'), //A4纸,纵向
ctx = canvas.getContext('2d'),
a4w = 190,
a4h = 247,
imgHeight = Math.floor((a4h * canvas.width) / a4w),
renderedHeight = 0;
while (renderedHeight < canvas.height) {
let page = document.createElement('canvas');
page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
//用getImageData剪裁指定区域,并画到前面创建的canvas对象中
page
.getContext('2d')
.putImageData(
ctx.getImageData(
0,
renderedHeight,
canvas.width,
Math.max(imgHeight, canvas.height - renderedHeight)
),
0,
0
);
pdf.addImage(
page.toDataURL('image/jpeg', 1.0),
'JPEG',
10,
30,
a4w,
Math.min(a4h, (a4w * page.height) / page.width)
);
renderedHeight += imgHeight;
if (renderedHeight < canvas.height) {
pdf.addPage(); //如果后面还有内容,添加一个空页
}
}
resolve({ PDF: pdf, name: pdfName });
// PDF.save(pdfName + '.pdf')
});
});
}, 500);
},
//压缩
zipChange(data) {
const zip = new JSZip();
data.forEach(async (item) => {
const { PDF, name } = item;
if (data.length === 1) {
PDF.save(`${name}.pdf`);
} else {
await zip.file(`${name}.pdf`, PDF.output('blob'));
}
if (data.length > 1) {
zip.generateAsync({ type: 'blob' }).then((content) => {
FileSaver.saveAs(content, this.planName + '.zip');
});
}
});
},
},
};
</script>