JavaScript丨使用 html2canvas+jspdf 打印指定 DOM 节点

1.使用 html2canvas 截图截下指定DOM节点,可保留完整的样式
2.使用 jspdf 添加图片,可打印、预览或下载
使用时调用函数并传入参数即可,operate相关代码可根据需求修改
注:此函数分页打印时所有页码均加上白边,白边高度由上偏移控制
注:此函数会将宽度超过952并且可用一页打印完的DOM节点使用横向打印

// 添加依赖包
{
  "html2canvas": "^1.4.1",
  "jspdf": "^2.5.1"
}

// 引入
import JsPDF from 'jspdf'
import html2Canvas from 'html2canvas'
/**
 * @param dom 要打印的DOM节点
 * @param pdfTitle PDF的文件名
 * @param operate 打印或下载
 */
async function htmlToPdf(dom, pdfTitle, operate) {
  // dom.style.zoom = 1.7
  return new Promise((resolve, reject) => {
    let PDF = new JsPDF('', 'pt', 'a4')
    html2Canvas(dom).then(function (canvas) {
      // dom.style.zoom = 1
      // 是否超出最大宽度(有滚动条)
      let overflow = dom.offsetWidth > 952
      // 是否横排
      let lPrint = false
      // 内容大小
      let contentWidth = canvas.width
      let contentHeight = canvas.height
      console.log('内容大小', contentWidth, contentHeight)
      // 左偏移(向右)、上偏移(向下)
      let positionX = 20
      let positionY = 20
      // 页面上下白边的高度
      let paddingY = positionY - 1
      console.log('左偏移', positionX)
      console.log('上偏移', positionY)
      // 纸张大小
      let A4Width = 595.28
      let A4Height = 841.89
      if (
        overflow &&
        contentHeight + 2 * positionX < (contentWidth / 841.89) * 595.28
      ) {
        console.log('内容溢出且能一页打完,使用横向打印表格')
        lPrint = true
        A4Width = 841.89
        A4Height = 595.28
      }
      console.log('A4纸张大小', A4Width, A4Height)
      let pageHeight = (contentWidth / A4Width) * A4Height
      console.log('页面高度', pageHeight)
      let leftHeight = contentHeight
      console.log('剩余未打印内容高度', leftHeight)
      let imgWidth = A4Width - 2 * positionX
      let imgHeight = (imgWidth / contentWidth) * contentHeight
      console.log('图片大小', imgWidth, imgHeight)
      let pageData = canvas.toDataURL('image/jpeg', 1)
      if (leftHeight < pageHeight - 2 * positionY) {
        // 水平
        if (lPrint) {
          PDF.deletePage(1)
          PDF.addPage([A4Width, A4Height], 'l')
        }
        PDF.addImage(
          pageData,
          'JPEG',
          positionX,
          positionY,
          imgWidth,
          imgHeight
        )
      } else {
        while (leftHeight > 0) {
          PDF.addImage(
            pageData,
            'JPEG',
            positionX,
            positionY,
            imgWidth,
            imgHeight
          )
          // 填充上方白边
          PDF.setFillColor(255, 255, 255)
          PDF.rect(0, 0, A4Width, paddingY, 'F')
          leftHeight = leftHeight - pageHeight + 2 * positionX
          positionY = positionY - A4Height + 2 * positionX
          console.log('剩余未打印内容高度', leftHeight)
          if (leftHeight > 0) {
            // 填充下方白边
            PDF.setFillColor(255, 255, 255)
            PDF.rect(0, A4Height - paddingY, A4Width, paddingY, 'F')
            PDF.addPage()
          }
        }
      }
      if (operate == 'download') {
        // 下载
        PDF.save(pdfTitle)
      }
      if (operate == 'print') {
        // 预览打印(注释代码可能白屏,无法预览和调起打印窗口)
        // PDF.autoPrint()
        // PDF.output('dataurlnewwindow')
        PDF.setProperties({ title: pdfTitle })
        let w = window.open(PDF.output('bloburl'), '_blank')
        w.print()
      }
      resolve()
    })
  })
}

你可能感兴趣的:(JavaScript,javascript,前端,开发语言)