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')
      },
相关推荐
江城开朗的豌豆10 分钟前
Vue+JSX真香现场:告别模板语法,解锁新姿势!
前端·javascript·vue.js
摸鱼仙人~19 分钟前
Vue.js 指令系统完全指南:深入理解 v- 指令
前端·javascript·vue.js
江城开朗的豌豆23 分钟前
Vue列表渲染的坑:为什么不能用index当key?血泪教训总结!
前端·javascript·vue.js
前端小巷子29 分钟前
Vue 虚拟 DOM
前端·vue.js·面试
江城开朗的豌豆31 分钟前
Vue中key的妙用:为什么你的列表渲染总出bug?
前端·javascript·vue.js
Zz_waiting.35 分钟前
Javaweb - 13 - AJAX
前端·javascript·ajax
小楓120140 分钟前
0基礎網站開發技術教學(一) --(前端篇)--
前端·javascript·css·html·web開發
张较瘦_1 小时前
[论文阅读] 人工智能 + 软件工程 | CASCADE:用LLM+编译器技术破解JavaScript混淆难题
javascript·论文阅读·人工智能
( ̄(工) ̄)霸天下1 小时前
Typescript速通教程
前端·javascript·typescript
程序视点1 小时前
PDF转Word免费工具!批量处理PDF压缩,合并, OCR识别, 去水印, 签名等全功能详解
pdf·pdf压缩·pdf编辑软件·pdf转换器·免费pdf工具·pdf转word免费工具·批量处理pdf的软件推荐