html下载pdf代码,实现手动分页

<script>
/**
 * @param html { String } DOM树
 * @param isOne { Boolean }  是否为单页 默认 否(false)
 * @return 文件 {pdf格式}
 */

'use strict'
import * as jsPDF from 'jspdf'
import html2canvas from 'html2canvas'

export default async (html, isOne) => {
  let contentWidth = html.clientWidth // 获得该容器的宽
  let contentHeight = html.clientHeight // 获得该容器的高
  let canvas = document.createElement('canvas')
  let scale = 2  // 解决清晰度问题,先放大 2倍

  canvas.width = contentWidth * scale // 将画布宽&&高放大两倍
  canvas.height = contentHeight * scale
  canvas.getContext('2d').scale(scale, scale)

  let opts = {
    scale: scale,
    canvas: canvas,
    width: contentWidth,
    height: contentHeight,
    useCORS: true
  }

  return html2canvas(html, opts).then(canvas => {
    let pageData = canvas.toDataURL('image/jpeg', 1.0) // 清晰度 0 - 1
    let pdf

    if (isOne) {
      // 单页
      console.log(contentWidth, 'contentWidth')
      console.log(contentHeight, 'contentHeight')

      // jspdf.js 插件对单页面的最大宽高限制 为 14400
      let limit = 14400

      if (contentHeight > limit) {
        let contentScale = limit / contentHeight
        contentHeight = limit
        contentWidth = contentScale * contentWidth
      }

      let orientation = 'p'
      // 在 jspdf 源码里,如果是 orientation = 'p' 且 width > height 时, 会把 width 和 height 值交换,
      // 类似于 把 orientation 的值修改为 'l' , 反之亦同。
      if (contentWidth > contentHeight) {
        orientation = 'l'
      }

      // orientation Possible values are "portrait" or "landscape" (or shortcuts "p" or "l")
      pdf = new jsPDF(orientation, 'pt', [contentWidth, contentHeight]) // 下载尺寸 a4 纸 比例

      // pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置
      pdf.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight)
    } else {
      //一页 pdf 显示 html 页面生成的 canvas高度
      let pageHeight = (contentWidth / 552.28) * 841.89
      //未生成 pdf 的 html页面高度
      let leftHeight = contentHeight
      //页面偏移
      let position = 0
      //a4纸的尺寸[595.28,841.89],html 页面生成的 canvas 在pdf中图片的宽高
      let imgWidth = 555.28
      let imgHeight = (imgWidth / contentWidth) * contentHeight

      pdf = new jsPDF('', 'pt', 'a4') // 下载尺寸 a4 纸 比例
      //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
      //当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < pageHeight) {
        pdf.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight)
      } else {
        while (leftHeight > 0) {
          pdf.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
          leftHeight -= pageHeight
          position -= 841.89
          //避免添加空白页
          if (leftHeight > 0) {
            pdf.addPage()
          }
        }
      }
    }
    return pdf
  })
}
</script>

以下为具体代码

分页逻辑

将需要转为pdf的dom用class拆开,然后将nodeLIst传入html2canvas

let elements = document.querySelectorAll('.pdf-box')
 this.h22p(filename,elements)

这里遇到的坑比较多,由于html2canvs是一个promise,如果在对其使用循环会导致paf.addImage()方法加载的图片不一样或者顺序问题,所以这里使用递归调用,在.then()里面进行递归

  h22p(filename,els) {
        let pdf = new jsPDF('', 'pt', 'a4')
        let flagArr = []
        for (let i = 0, len = els.length; i < len; i++) {
          flagArr.push(0)
        }
        runself(0)
        let _this=this
        function runself(index) {
          let html=els[index];
          // [...els].map((html, index) => {
            let contentWidth = html.clientWidth // 获得该容器的宽
            let contentHeight = html.clientHeight // 获得该容器的高
            let canvas = document.createElement('canvas')
            let scale = 2 // 解决清晰度问题,先放大 2倍
            canvas.width = contentWidth * scale // 将画布宽&&高放大两倍
            canvas.height = contentHeight * scale
            canvas.getContext('2d').scale(scale, scale)
            let opts = {
              // scale: scale,
              canvas: canvas,
              width: contentWidth,
              height: contentHeight,
              useCORS: true
            }
            html2canvas(html, opts).then(canvas => {
              let pageData = canvas.toDataURL('image/jpeg', 1.0) // 清晰度 0 - 1
              let imgWidth = 555.28
              let imgHeight = (imgWidth / contentWidth) * contentHeight
              // pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置
              pdf.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight)
              pdf.addPage()
              return 1
            }).then(item => {
              flagArr[index] = item
              if (flagArr.every(f => f === 1)) {
                pdf.save('filename'+'pdf')
                _this.loadingsisShow=false
              }
              if (index < els.length) {
                index++
                runself(index)
              }
            })
          // })
        }
      }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值