前言

最近在项目中,有一个导出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文件里面配置(引入、挂载)

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

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

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

  1. <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完整方法

  1. downPdf () {
    注意:生成的pdf只有页面窗口可见的区域,有滚动条的下面没有生成出来(要注意这里是一个坑)
    如果截取是body的这个层级,而刚好body设置了overflow: hidden;那超出的部分是永远截取不到的,因为这个节点的dom高就是窗口可见的高度,并不包含滚动条多出来的部分
    解决办法只需要在导出之前将overflow:auto设置成visible(默认即可)
    导出pdf后再设置回去
  1.    // 导出之前将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'})
  2.  
  3. // 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自适应大小不分页处理:

  1. // 下载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%'})
    }

纯前端html导出pdf--分页+不分页--html2canvas+jsPDF的更多相关文章

  1. c# 通过html导出pdf,带分页

    通过NuGet安装 PechkinPechkin.Synchronized 一下示例是控制台应用程序 static void btnCreate() { SynchronizedPechkin sc ...

  2. 前端 / JavaScript 导出PDF的实践

    1.库:jspdf,自己定义一个高宽,如A4的210mm×297mm 2.让设计给背景图(包括:页眉页脚),水印图(背景透明,高宽和你的PDF单页一致)以及很多,能设计给的设计要给,因为在pdf上,排 ...

  3. 纯前端导出pdf文件

    纯前端js导出pdf,已经用于生产环境. 工具: 1.html2canvas,一种让html转换为图片的工具. 2.pdfmake或者jspdf ,一种生成.编辑pdf,并且导出pdf的工具. pdf ...

  4. 前端导出pdf

    html2canvas文档地址 http://html2canvas.hertzen.com/configuration 方式一:使用html2canvas和jspdf插件实现 该方式是通过html2 ...

  5. JS导出PDF插件(支持中文、图片使用路径)

    在WEB上想做一个导出PDF的功能,发现jsPDF比较多人推荐,遗憾的是不支持中文,最后找到pdfmake,很好地解决了此问题.它的效果可以先到http://pdfmake.org/playgroun ...

  6. 纯前端下载pdf链接文件,而不是打开预览的解决方案

    纯前端下载pdf链接文件,而不是打开预览的解决方案 一,介绍与需求 1.1,介绍 XMLHttpRequest 用于在后台与服务器交换数据.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行 ...

  7. vue后台_纯前端实现excel导出/csv导出

    之前的文件下载功能一般是由前后端配合实现,由于项目需要,纯前端实现了一把excel的导出功能: 一.excel导出 1.安装依赖库 xlsx:这是一个功能强大的excel处理库,但是上手难度也很大,还 ...

  8. java根据模板导出PDF详细教程

    原文:https://blog.csdn.net/pengyufight/article/details/75305128 题记:由于业务的需要,需要根据模板定制pdf文档,经测试根据模板导出word ...

  9. JSP页面导出PDF格式文件

    JSP页面导出PDF格式文件基本在前端页面可以全部完成 <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/ ...

随机推荐

  1. Docker部署Flask应用

    创建应用 首先,编写一个简单的Flask应用:docker_test/flask_app.py Docker 安装 请根据自己的操作系统自行安装. Docker简介 Docker 镜像 Docker镜 ...

  2. 【leetcode】946. Validate Stack Sequences

    题目如下: Given two sequences pushed and popped with distinct values, return true if and only if this co ...

  3. 使用 v-html 绑定值

    <div id="app03"> <div v-html="message"></div> <!--这里使用v-htm ...

  4. django 框架下的路由分发

  5. JindoFS解析 - 云上大数据高性能数据湖存储方案

    JindoFS背景 计算存储分离是云计算的一种发展趋势,传统的计算存储相互融合的的架构存在一定的问题, 比如在集群扩容的时候存在计算能力和存储能力相互不匹配的问题,用户在某些情况下只需要扩容计算能力或 ...

  6. 低价购买 (动态规划,变种最长下降子序列(LIS))

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  7. Python每日一题 007

    题目 你有一个目录,放了你一个月的日记,都是 txt,为了避免分词的问题,假设内容都是英文,请统计出你认为每篇日记最重要的词. 很难客观的说每篇日记中最重要的词是什么,所以在这里就仅仅是将每篇日记中出 ...

  8. Android 测试点归纳总结

    前言 除了测试平台工具,业务测试的总结和思考同样重要,这里总结了一些Android测试知识点,可以辅助业务测试快速形成测试用例和检查点,当作抛砖引玉分享给大家.如有思考不全面的地方,欢迎大家指出来. ...

  9. Callable创建线程

    (1)Callable接口更像是Runnable接口的增强版,相比较Runable接口,Call()方法新增捕获和抛出异常的功能;Call()方法可以返回值<br> (2)Future接口 ...

  10. WebBrowser常用浏览操作

    WebBrowser1.GoHome; //到浏览器默认主页 WebBrowser1.Refresh; //刷新 WebBrowser1.GoBack; //后退 WebBrowser1.GoForw ...