纯前端如何实现批量下载功能呢?

纯前端如何实现批量下载功能呢?

***需求:***在不依赖后端的情况下,前端需要独立实现批量下载,且下载的文件需统一放在一个文件夹中并压缩
插件:

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>
相关推荐
hackeroink1 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者2 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-3 小时前
验证码机制
前端·后端
燃先生._.4 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖5 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235245 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240256 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar6 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人6 小时前
前端知识补充—CSS
前端·css