JS - 导出一个或多个pdf 生成zip压缩包

前端生成和导出pdf zip;

使用的插件:jspdf、html2canva、jszip、file-saver

插件安装  :npm install jspdf html2canvas jszip file-saver

可用于单个导出pdf ,或者多个 直接生成压缩包

ps:这里演示代码使用场景是:zip文件里多个pdf (自行修改)

pdf.js

//PDF.js
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
/**
 * 网页转pdf
 * @param {*} dom 指定区域
 * @param {*} name 文件名
 */
export const downloadPDF = (dom, name) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      var _downDOM = dom
      // 导出之前先将滚动条置顶,不然会出现数据不全的现象
      window.pageYOffset = 0
      document.documentElement.scrollTop = 0
      document.body.scrollTop = 0
      html2canvas(_downDOM, {
        scale: 4, //按比例增加分辨率 (2=双倍).
        dpi: window.devicePixelRatio * 4, //设备像素比
      }).then((canvas) => {
        var contentWidth = canvas.width
        var contentHeight = canvas.height
        // console.log(contentWidth + '||' + contentHeight)
        //一页pdf显示html页面生成的canvas高度;
        var pageHeight = (contentWidth / 592.28) * 841.89
        //未生成pdf的html页面高度
        var leftHeight = contentHeight
        //页面偏移
        var position = 0
        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        var imgWidth = 555.28
        var imgHeight = (555.28 / contentWidth) * contentHeight
        var pageData = new Image()
        //设置图片跨域访问
        pageData.setAttribute('crossOrigin', 'Anonymous')
        pageData = canvas.toDataURL('image/jpeg', 1.0)
        var pdf = new jsPDF('', 'pt', 'a4')
        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围,无需分页
        if (leftHeight < pageHeight) {
          pdf.addImage(pageData, 'JPEG', 20, 80, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 841.89
            //避免添加空白页
            if (leftHeight > 0) {
              pdf.addPage()
            }
          }
        }
        //这里返回文件 用来处理多个下载 打包zip
        resolve({ PDF: pdf, name: name })
        //直接单个pdf可直接调用下面方法
        // pdf.save(name)
      })
    }, 10)
  })
}

 template中使用


import JSZip from 'jszip'
import FileSaver from 'file-saver'
import { downloadPDF } from '@/utils/pdf' //引入封装的pdf.js文件

 /**
  * 触发下载
  */
 async download() {
  let promises = []
  //downloadTaskList 为下载的长度,我这里是为发票数组
  for (let i = 0; i < this.downloadTaskList.length; i++) {
     //dom 具体传入参数 自行修改
     let PDFres = await downloadPDF(this.$refs[`pdf${this.downloadTaskList[i].code}`][0], `${this.downloadTaskList[i].realName}-${this.downloadTaskList[i].code}`)
     promises.push(PDFres)
     const loading = this.$loading({
        lock: true,
        text: 'loading...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
     //动态提示需要等待生成文件
     loading.setText(`正在生成第${i + 1}/${this.downloadTaskList.length}份回执单`)
     if (i === this.downloadTaskList.length - 1) {
      this.zipChange(promises)
      loading.close()
     }
   }
},
/**
 *生成zip
 */
zipChange(promises) {
    Promise.all(promises).then(async(pdfs) = >{
        const zip = new JSZip() 
        promises.forEach(async(item, index) = >{
            const {PDF,name} = item
            if (promises.length === 1) {
                PDF.save(`$ {name}.pdf`)
            } else {
                await zip.file(`$ {name}.pdf`, PDF.output('blob'))
            }
        }) 
        if (promises.length > 1) {
            zip.generateAsync({type: 'blob'}).then((content) = >{
                FileSaver.saveAs(content, '回执' + '.zip')
            })
        }
    })
},

你可能感兴趣的:(JS,前端,vue.js,javascript)