Vue 实现页面导出A4标准大小的PDF文件,以及处理图片跨域不能正常展示的问题等

效果预览:

代码流程:首先在utils文件夹下创建htmlToPdf的js工具文件,然后在main.js中注册引用

htmlToPdf.js

复制代码
// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'

export default {
  install(Vue, options) {
    Vue.prototype.getPdf = function (id) {
      var title = '导出试卷'
      if (id === null || id === undefined) {
        id = '#pdfDom'
      }
      html2Canvas(document.querySelector(id), {
        allowTaint: true,
      }).then(function (canvas) {
        const contentWidth = canvas.width
        const contentHeight = canvas.height
        const pageData = canvas.toDataURL('image/jpeg', 1.0)
        const pdfX = contentWidth
        const pdfY = contentHeight // 500为底部留白
        const imgX = contentWidth
        const imgY = contentHeight // 内容图片这里不需要留白的距离
        const PDF = new JsPDF('', 'pt', [pdfX, pdfY])
        PDF.addImage(pageData, 'jpeg', 0, 0, imgX, imgY)
        PDF.save(title + '.pdf')
      })
    }

    Vue.prototype.getPdfByIds = function (pages) {
      var title = '导出试卷'
      let params = []
      let PDF = null

      let imgs = document.querySelectorAll('img')
      for (let img of imgs) {
        img.setAttribute('crossorigin', '*')
      }
      let parentNode = document.querySelector(pages)
      let promises = []
      for (let i = 0; i < parentNode.childNodes.length; i++) {
        let promise = new Promise((res, rej) => {
          let pageIndex = i
          html2Canvas(
            document.querySelector('#' + parentNode.childNodes[i].id),
            {
              allowTaint: true,
              // useCORS: true,
            }
          )
            .then(function (canvas) {
              const contentWidth = canvas.width
              const contentHeight = canvas.height
              let pageData = canvas.toDataURL('image/jpeg', 1.0)
              let pdfWidth = contentWidth
              let pdfHeight = contentHeight // 500为底部留白
              let imgX = contentWidth
              let imgY = contentHeight // 内容图片这里不需要留白的距离

              params.push({
                pageIndex: pageIndex,
                pageData: pageData,
                pdfWidth: pdfWidth,
                pdfHeight: pdfHeight,
              })

              res(PDF)
            })
            .catch((e) => {
              console.log('报错', e)
            })
        })
        promises.push(promise)
      }
      Promise.all(promises).then((val) => {
        params.sort(function (a, b) {
          let index1 = a['pageIndex']
          let index2 = b['pageIndex']
          return index1 - index2 //正序
        })
        let i = 0
        for (let param of params) {
          i++
          console.log('param', param)
          let pdfWidth = param['pdfWidth']
          let pdfHeight = param['pdfHeight']
          let pageData = param['pageData']

          if (PDF === null) {
            PDF = new JsPDF('', 'pt', [pdfWidth, pdfHeight])
          } else {
            PDF.addPage()
          }
          PDF.addImage(pageData, 'jpeg', 0, 0, pdfWidth, pdfHeight)
        }
        if (params.length == parentNode.childNodes.length) {
          PDF.save(title + '.pdf')
        }
      })
    }

    Vue.prototype.getPdfByIdsB = function (pages) {
      var title = '导出试卷'
      let params = []
      let PDF = null

      let imgs = document.querySelectorAll('img')
      for (let img of imgs) {
        img.setAttribute('crossorigin', '*')
      }
      let parentNode = document.querySelector(pages)
      let promises = []
      for (let i = 0; i < parentNode.childNodes.length; i++) {
        let promise = new Promise((res, rej) => {
          let pageIndex = i
          html2Canvas(
            document.querySelector('#' + parentNode.childNodes[i].id),
            {
              allowTaint: true,
              useCORS: true,
            }
          )
            .then(function (canvas) {
              const contentWidth = canvas.width
              const contentHeight = canvas.height
              let pageData = canvas.toDataURL('image/jpeg', 1.0)
              let pdfWidth = contentWidth
              let pdfHeight = contentHeight // 500为底部留白
              let imgX = contentWidth
              let imgY = contentHeight // 内容图片这里不需要留白的距离
              params.push({
                pageIndex: pageIndex,
                pageData: pageData,
                pdfWidth: pdfWidth,
                pdfHeight: pdfHeight,
              })

              res(PDF)
            })
            .catch((e) => {
              console.log('报错', e)
            })
        })
        promises.push(promise)
      }
      Promise.all(promises).then((val) => {
        params.sort(function (a, b) {
          let index1 = a['pageIndex']
          let index2 = b['pageIndex']
          return index1 - index2 //正序
        })
        let i = 0
        for (let param of params) {
          i++
          console.log('param', param)
          let pdfWidth = param['pdfWidth']
          let pdfHeight = param['pdfHeight']
          let pageData = param['pageData']

          if (PDF === null) {
            PDF = new JsPDF('', 'pt', [pdfWidth, pdfHeight])
          } else {
            PDF.addPage()
          }
          PDF.addImage(pageData, 'jpeg', 0, 0, pdfWidth, pdfHeight)
        }
        if (params.length == parentNode.childNodes.length) {
          PDF.save(title + '.pdf')
        }
      })
    }
  },
}

在main.js中注册引用,挂载全局即可使用

复制代码
import htmlToPdf from './utils/htmlToPdf'
Vue.use(htmlToPdf)

下载方法中,使用即可,#app为最外层父级元素id名称

复制代码
//下载
      downloadPapaers() {
        Vue.prototype.getPdfByIdsB('#app')
      },
相关推荐
harry7591 分钟前
Flex-1 布局实现内部滚动条
前端·javascript·css
很酷爱学习2 分钟前
js内存泄漏的几种情况、js垃圾回收机制、内存机制
javascript
jqq6662 分钟前
(一)「造轮子」我也写了个Vue3脚手架!(整体介绍)
前端·javascript·vue.js
the_one3 分钟前
🚀让动画动起来!用 CSS 延迟变量打造交互式炫酷小球动画
前端·javascript·css
一梦南柯5 分钟前
浏览器调试实战:从前端开发到线上问题定位的高效技巧全解析
前端·vue.js·浏览器
阿炸7 分钟前
js中原型链实现继承——最佳实践
前端·javascript
赵晟鼎11 分钟前
node常用fs文件操作方法
前端·javascript·node.js
_Hannibal_18 分钟前
通过百度OCR在线API识别带水印扫描图片文字
pdf·ocr
HaSaKing_72123 分钟前
【完整可用】使用openhtmltopdf生成PDF(带SVG)
pdf·openhtmltopdf
拖孩1 小时前
微信小程序基于Canvas实现头像图片裁剪(下)
前端·javascript·微信小程序