• 纯前端html导出pdf--分页+不分页--html2canvas+jsPDF


    前言

    最近在项目中,有一个导出pdf功能,需要纯前端来实现,调研了多种pdf导出方式,最终决定使用html2canvas+jsPDF来实现需求。

    本文就简单介绍一下html2canvas+jsPDF导出pdf的实现,网上大部分实现导出pdf都是以分页为主的,本文还将附上不分页导出pdf的实现方法。(只附js代码)

    html2canvas+jsPDF导出pdf原理:通过html2canvas将遍历页面元素,并渲染生成canvas,然后将canvas图片格式添加到jsPDF实例,生成pdf。

    安装:

    npm install html2canvas --save

    npm install jsPDF --save

    配置:

    main.js文件里面配置(引入、挂载)

    import html2canvas from 'html2canvas'
    import jsPDF from 'jsPDF '
    Vue.prototype.html2canvas = html2canvas
    Vue.prototype.jsPDF = jsPDF 

    或者--------------------------------------------------------------------------------

    index.html页面直接引入js文件:

    <script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
    <script src="https://cdn.bootcss.com/jspdf/1.3.4/jspdf.debug.js"></script>

    导出pdf按a4纸大小分页处理:// 下载pdf完整方法

    downPdf () {
    注意:生成的pdf只有页面窗口可见的区域,有滚动条的下面没有生成出来要注意这里是一个坑
    果截取是body的这个层级,而刚好body设置了overflow: hidden;那超出的部分是永远截取不到的,因为这个节点的dom高就是窗口可见的高度,并不包含滚动条多出来的部分
    决办法只需要在导出之前将overflow:auto设置成visible(默认即可)
    导出pdf后再设置回去
       // 导出之前将dom的overflow:auto设置成visible    
       this.$('#boardPdf').css({'overflow-y': 'visible', 'height': 'auto'})
    this.$('#app').css({'overflow-y': 'visible', 'height': 'auto'})
    this.$('body').css({'overflow-y': 'visible', 'height': 'auto'})

    // eslint-disable-next-line
    html2canvas(document.querySelector('#boardPdf'), {
    scale: 2,
    onrendered: function (canvas) {
    var contentWidth = canvas.width
    var contentHeight = canvas.height
    // 一页pdf显示html页面生成的canvas高度;
    var pageHeight = contentWidth / 592.28 * 841.89
    // 未生成pdf的html页面高度
    var leftHeight = contentHeight
    // pdf页面偏移
    var position = 0
    // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
    var imgWidth = 595.28
    var imgHeight = 592.28 / contentWidth * contentHeight
    var pageData = canvas.toDataURL('image/jpeg', 1.0)
    // eslint-disable-next-line
    var pdf = new jsPDF('', 'pt', 'a4')
    // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
    // 当内容未超过pdf一页显示的范围,无需分页
    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()
    }
    }
    }
           // 导出pdf文件命名
    pdf.save('report_pdf_' + new Date().getTime() + '.pdf')
    },
    background: '#0B1A48'
    })
      // 导出pdf后,将dom原本的属性设置回去
    this.$('#boardPdf').css({'overflow-y': 'auto', 'height': '100%'})
    this.$('#app').css({'overflow-y': 'auto', 'height': '100%'})
    this.$('body').css({'overflow-y': 'auto', 'height': '100%'})
    }

    导出pdf自适应大小不分页处理:

    // 下载pdf完整方法
    downPdf () {
    // 生成的pdf只有页面窗口可见的区域,有滚动条的下面没有生成出来,需在生成PDF前,改overflow属性auto为visible
    this.$('#boardPdf').css({'overflow-y': 'visible', 'height': 'auto'})
    this.$('#app').css({'overflow-y': 'visible', 'height': 'auto'})
    this.$('body').css({'overflow-y': 'visible', 'height': 'auto'})
    // 获取dom高度、宽度
    var shareContent = document.querySelector('#boardPdf')
    var width = shareContent.offsetWidth / 4
    var height = shareContent.offsetHeight / 4
    let _this = this
    // eslint-disable-next-line
    html2canvas(document.querySelector('#boardPdf'), {
    onrendered: function (canvas) {
    var context = canvas.getContext('2d')
    context.mozImageSmoothingEnabled = false
    context.webkitImageSmoothingEnabled = false
    context.msImageSmoothingEnabled = false
    context.imageSmoothingEnabled = false
    var pageData = canvas.toDataURL('image/jpeg', 1.0)
    var img = new Image()
    img.src = pageData
    img.onload = function () {
    // 获取dom高度、宽度
    img.width = img.width / 2
    img.height = img.height / 2
    img.style.transform = 'scale(0.5)'
    if (width > height) {
    // 此可以根据打印的大小进行自动调节
    // eslint-disable-next-line
    var pdf = new jsPDF('l', 'mm', [
    width * 0.505,
    height * 0.545
    ])
    } else {
    // eslint-disable-next-line
    var pdf = new jsPDF('p', 'mm', [
    width * 0.505,
    height * 0.545
    ])
    }
    pdf.addImage(
    pageData,
    'jpeg',
    0,
    0,
    width * 0.505,
    height * 0.545
    )
    pdf.save(_this.boardNameTitle + '.pdf')
    }
    },
    background: '#0B1A48'
    })
      // 导出pdf后,将dom原本属性设置回去
    this.$('#boardPdf').css({'overflow-y': 'auto', 'height': '100%'})
    this.$('#app').css({'overflow-y': 'auto', 'height': '100%'})
    this.$('body').css({'overflow-y': 'auto', 'height': '100%'})
    }
  • 相关阅读:
    20181120-1 每周例行报告
    20181113-2 每周例行报告
    20181030-4 每周例行报告
    20181023-3 每周例行报告
    第六周例行报告
    软件功能说明书final修订
    第十二周——例行报告
    PSP总结报告
    第十一周——例行报告
    PSP Daily软件beta版本——基于NABCD评论,及改进建议
  • 原文地址:https://www.cnblogs.com/candy-xia/p/11155754.html
Copyright © 2020-2023  润新知