纯前端HTML转PDF下载(html2canvas + jsPdf 实现)

2,574 阅读2分钟

转载

纯前端HTML转PDF下载(html2canvas + jsPdf 实现) 最近的一个需求,需要将页面的内容转为PDF并且下载,通过搜索终于实现了想要的效果,以下是一些笔记内容。

实现过程 我们会用到html2Canvas和JsPDF去实现。 1.html2Canvas会将html页面截屏并转为canvas 2.然后利用JsPDF将canvas图片排版后下载保存。

安装好html2canvas和jspdf html2canvas官网 和 jspdf官网

npm insatll --save html2canvas jspdf

image.png

jspdf参数

// jspdf部分源码
constructor(orientation?:any, // 方向
            unit?:string,// 单位
            format?:string|Array<Number>,// 格式(字符串'a4'或数组[100,200])
            compressPdf?:number);// 压缩Pdf
            
//添加页面(用于换页)
addPage(format?: string | number[], orientation?: 'p'|'portrait'|'l'|'landscape'): jsPDF;//格式,方向

//保存/下载页面
save(filename:string, options: {returnPromise: boolean}): Promise<any>;//文件名,是否返回promise(可用于判断下载是否完成)


let PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])// 方向,单位,格式,压缩Pdf

应用 首先我们在 utils 中创建 htmlToPdf.js 文件,封装一个getPdf 方法,并挂载到Vue原型上

// 导出页面为PDF格式
// 引入依赖
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
  install(Vue, options) {
    Vue.prototype.getPdf = async (title) => {
      let result
      var element = document.querySelector('#pdfDom') // 这个dom元素是要导出pdf的div容器
      var w = element.offsetWidth // 获得该容器的宽
      var h = element.offsetHeight // 获得该容器的高
      var canvas = document.createElement('canvas')
      canvas.width = w * 4 // 将画布宽&&高放大两倍
      canvas.height = h * 4 
      var scale = 4 // 数值和上面一样,数字越大越清晰
	
      var opts = {
        scale: scale,
        canvas: canvas,
        width: w,
        height: h,
        useCORS: true,
        background: '#FFF'
      }

      await html2Canvas((element), {
        ...opts,
        allowTaint: false,
        taintTest: false
      }).then(function (canvas) {
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        let pageHeight = (contentWidth - 10) / 592.28 * 841.89
        let leftHeight = contentHeight
        // let position = 10
        let imgWidth = 595.28
        let imgHeight = 592.28 / contentWidth * contentHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        let PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])// 可以自定义宽度,也可以用a4,a3等等
        if (leftHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 841.89
            if (leftHeight > 0) {
              PDF.addPage()
            }
          }
        }
        result = PDF.save(title + '.pdf', { returnPromise: true })//返回promise用于判断是否下载完成,便于实现局部loading哦~
      }
      )
      return result //最后返回这个promise啦,在外面用then就可以接收res咯
    }
  }
}

几个应用的点
自定义页面大小

let PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])
1
页面边距设置

PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) //设置左边距和上边距
1
如何监听下载完成

//通过设置options{ returnPromise: true },返回一个promise,通过判断promise的状态可以实现监听效果
PDF.save(title + '.pdf', { returnPromise: true })