实际开发需求:vue项目中,根据数据结构生成echarts图表组件,生成带有样式的图表以后,点击下载按钮,把图表以pdf格式的文件下载到本地

实现思路:将vue界面的echarts组件生成图片,然后使用插件将生成的图片放入pdf中,再实现pdf文件的下载

涉及框架以及插件:vue、echarts、html2canvas、dom-to-image、jspdf

插件介绍:

vue、echarts 不用多说,vue前端的框架,echarts用来根据数据生成的带有样式效果的图表;html2canvas与dom-to-image都是将界面上的dom生成图片。

html2canvas

能够实现在用户浏览器端直接对整个或部分页面进行生成图片,主要是将选中的页面或者整个页面渲染成一个canvas图片,通过读取DOM并将不同的样式应用到这些元素上实现。可以通过获取HTML的某个元素,然后生成Canvas,从而生成图片。

  1. 安装
  2. npm install --save html2canvas
  3. yarn add html2canvas
  4. 引入
  5. import html2canvas from 'html2canvas';

用法:

  1. <div class="container" id="myDom1">
  2. 测试
  3. </div>
  4. <style>
  5. .container {
  6. width:100px;
  7. height:100px;
  8. background:red;
  9. color: #ffffff;
  10. }
  11. </style>
  12. methods(){
  13. getImage(){
  14. html2canvas(document.querySelector("#myDom1")).then(canvas => {
  15. console.logo(canvas)
  16. document.body.appendChild(canvas);
  17. var dataUrl = canvas.toDataURL("image/png")
  18. });
  19. }
  20. }
参数名称 类型 默认值 描述
allowTaint boolean false 允许跨域
background string #fff canvas的背景颜色,如果没有设定默认透明
height number null canvas高度设定
letterRendering boolean false 在设置了字间距的时候有用
logging boolean false 输出信息
proxy string undefined 代理地址
taintTest boolean true 是否在渲染前测试图片
timeout number 0 图片加载延迟,默认延迟为0,单位毫秒
width number null canvas的宽度
useCORS boolean false 图片跨域问题

dom-to-image

它可以将任意DOM节点转换成用JavaScript编写的矢量(SVG)或光栅(PNG或JPEG)图像。

  1. 安装
  2. npm install dom-to-image
  3. yarn add dom-to-image
  4. 引入
  5. import domtoimage from 'dom-to-image';
  6. var domtoimage = require('dom-to-image');

基本用法:

  1. <template>
  2. <div id=""myDom>
  3. <el-table
  4. :data="tableData"
  5. style="width: 100%">
  6. <el-table-column
  7. prop="date"
  8. label="日期"
  9. width="180">
  10. </el-table-column>
  11. <el-table-column
  12. prop="name"
  13. label="姓名"
  14. width="180">
  15. </el-table-column>
  16. <el-table-column
  17. prop="address"
  18. label="地址">
  19. </el-table-column>
  20. </el-table>
  21. ......
  22. </div>
  23. </template>
  24. methods(){
  25. getDomToImage(){
  26. let dom = document.getElementById('myDom');
  27. domtoimage.toPng(dom).then(function (dataUrl) {
  28. var img = new Image();
  29. img.src = dataUrl;
  30. document.body.appendChild(img);
  31. })
  32. .catch(function (error) {
  33. console.error('wrong!', error);
  34. });
  35. }
  36. }

获取一个png的blob:

  1. domtoimage.toBlob(document.getElementById('myDom')).then(function (blob) {
  2. console.log(blob)
  3. });

jspdf

jsPDF 是一个使用 Javascript 语言生成 PDF 的开源库。你可以在 Firefox 插件,服务端脚本或是浏览器脚本中使用它。

  1. 安装:
  2. npm install jspdf
  3. yarn add jspdf
  4. 引入
  5. import jsPDF from "jspdf"

基本用法:

  1. let pdf = new jsPDF('p', 'pt', 'a4);
  2. 参数1:l:横向 p:纵向
  3. 参数2:单位("pt","mm", "cm", "m", "in" or "px")
  4. 参数3:格式,默认为“a4”

常用方法:

  1. pdf.addPage() PDF文档中添加新页面,参数如下,也可以不设置,默认a4
  2. pdf.addImage() 将图像添加到PDF
  3. pdf.save(`保存的PDF文件.pdf`); 保存为pdf格式的文件

回到需求:vue项目中,根据数据结构生成echarts图表组件,生成带有样式的图表以后,点击下载按钮,把图表以pdf格式的文件下载到本地(带分页),部分代码如下(思路)

1.使用html2canvas
  1. <template>
  2. <div id="pdfDom" ref="pdfDom">
  3. // 此处存放界面中显示的内容区域,生成pdf的内容区域......
  4. </div>
  5. </template>
  6. methods(){
  7. let node = document.getElementById('pdfDom');
  8. html2canvas(document.getElementById('pdfDom'), {
  9. scale: 2
  10. }).then(function (canvas) {
  11. var pdfWidth = canvas.width;
  12. var pdfHeight = canvas.height;
  13. var pageHeight = pdfWidth / 592.28 * 841.89;
  14. var leftHeight = pdfHeight;
  15. var position = 0;
  16. var imgWidth = 595.28;
  17. var imgHeight = 595.28 / pdfWidth * pdfHeight;
  18. var pageData = canvas.toDataURL("img/jpeg", 1.0);
  19. var pdf = new jsPDF('', 'pt', 'a4');
  20. // 判断打印dom高度是否需要分页,如果需要进行分页处理
  21. if (leftHeight < pageHeight) {
  22. pdf.addImage(pageData, "JPEG", 0, 0, imgWidth, imgHeight)
  23. } else {
  24. while (leftHeight > 0) {
  25. pdf.addImage(pageData, "JPEG", 0, position, imgWidth, imgHeight)
  26. leftHeight -= pageHeight
  27. position -= 841.89
  28. if (leftHeight > 0) {
  29. pdf.addPage()
  30. }
  31. }
  32. }
  33. const aLink = document.createElement('a')
  34. document.body.appendChild(aLink)
  35. const url = URL.createObjectURL(_this.toBlob(pdf.output('datauristring')))
  36. aLink.href = url
  37. let date = new Date()
  38. let year = date.getFullYear()
  39. let month = (date.getMonth() + 1).toString().padStart(2, 0)
  40. let day = date.getDate().toString().padStart(2, 0)
  41. let hour = date.getHours().toString().padStart(2, 0)
  42. let minutes = date.getMinutes().toString().padStart(2, 0)
  43. let seconds = date.getSeconds().toString().padStart(2, 0)
  44. aLink.download = '保存的PDF文件-' + '.pdf'
  45. aLink.click()
  46. window.URL.revokeObjectURL(url)
  47. })
  48. }
2.使用dom-to-image
  1. <template>
  2. <div id="pdfDom" ref="pdfDom">
  3. // 此处存放界面中显示的内容区域,生成pdf的内容区域......
  4. </div>
  5. </template>
  6. methods(){
  7. let node = document.getElementById('pdfDom');
  8. domtoimage.toJpeg(node, {
  9. width: node.clientWidth,
  10. height: node.clientHeight,
  11. cacheBust: true,
  12. style: {
  13. margin: 0,
  14. background: '#fff',
  15. }
  16. }).then(function (dataUrl) {
  17. console.log(node.clientWidth)
  18. that.canvasWidth = node.clientWidth;
  19. that.canvasHeight = node.clientHeight;
  20. let imgObj = new Image()
  21. imgObj.src = dataUrl;
  22. document.documentElement.scrollTop = 0
  23. //待图片加载完后,将其显示在canvas上
  24. imgObj.onload = function (img) {
  25. let canvas = document.getElementById("canvasDom");
  26. console.log(canvas.width, canvas.height, 'canvas.width')
  27. canvas.getContext("2d").drawImage(imgObj, 0, 0, that.canvasWidth, that.canvasHeight); //将图片绘制到canvas中
  28. let contentWidth = canvas.width
  29. let contentHeight = canvas.height
  30. let pageHeight = contentWidth / 592.28 * 841.89
  31. let leftHeight = contentHeight
  32. let position = 0
  33. let imgWidth = 595.28
  34. let imgHeight = 592.28 / contentWidth * contentHeight
  35. let pageData = canvas.toDataURL('image/jpeg', 1.0)
  36. let PDF = new jsPDF('', 'pt', 'a4')
  37. if (leftHeight < pageHeight) {
  38. PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight) // 大于1页高度时分页
  39. } else {
  40. while (leftHeight > 0) {
  41. PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
  42. leftHeight -= pageHeight
  43. position -= 841.89
  44. if (leftHeight > 0) {
  45. PDF.addPage()
  46. }
  47. }
  48. }
  49. const aLink = document.createElement('a')
  50. document.body.appendChild(aLink)
  51. const url = URL.createObjectURL(that.toBlob(PDF.output('datauristring')))
  52. aLink.href = url
  53. let date = new Date()
  54. let year = date.getFullYear()
  55. let month = (date.getMonth() + 1).toString().padStart(2, 0)
  56. let day = date.getDate().toString().padStart(2, 0)
  57. let hour = date.getHours().toString().padStart(2, 0)
  58. let minutes = date.getMinutes().toString().padStart(2, 0)
  59. let seconds = date.getSeconds().toString().padStart(2, 0)
  60. aLink.download = '保存的PDF文件-' + '.pdf'
  61. aLink.click()
  62. window.URL.revokeObjectURL(url)
  63. }
  64. return dataUrl
  65. })
  66. .catch(function (error) {
  67. console.error('wrong!', error);
  68. });
  69. }

vue前端实现将页面显示内容生成pdf文件的几种方法,html2canvas、dom-to-image、jspdf(带分页)基本使用以及介绍的更多相关文章

  1. 前端axios请求二进制数据流转换生成PDF文件空白问题(终极解决方案)

    本文章共1570字,预计阅读时间1 - 3分钟. 问题场景: axios请求二进制数据转换生成PDF空白问题,使用axios请求后端接口,后端返回的二进制流文件,需要转换成PDF,但是在postman ...

  2. .net生成PDF文件的几种方式

    以下为在.net mvc中,生成pdf的几种方式,资料都是在做项目时网上找的 1.使用Microsoft.Office.Interop.Word.dll将word转换为PDF dll可以单独下载,一般 ...

  3. PHP中的生成XML文件的4种方法(转)

    <?xml version="1.0" encoding="utf-8"?> <article> <item> <ti ...

  4. 生成mif文件的几种方法总结

    mif文件就是存储器初始化文件,即memory initialization file,用来配置RAM或ROM中的数据.生成QuartusII11.0可用的mif文件,有如下几种方式: 方法1:利用Q ...

  5. PHP中的生成XML文件的4种方法分享

    生成如下XML串 Xml代码 <?xml version="1.0" encoding="utf-8"?> <article> < ...

  6. 关于java poi itext生成pdf文件的例子以及方法

    最近正在做导出pdf文件的功能,所以查了了一些相关资料,发现不是很完善,这里做一些小小的感想,欢迎各位“猿”童鞋批评指正. poi+itext,所需要的jar包有itext-2.1.7.jar,poi ...

  7. Django(四) 后台管理:创建管理员、注册模型类、自定义管理页面显示内容

    后台管理 第1步.本地化:设置语言.时区 修改project1/settings.py #LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' #设置语言 ...

  8. 将HTML页面自动保存为PDF文件并上传的两种方式(一)-前端(react)方式

    一.业务场景 公司的样本检测报告以React页面的形式生成,已调整为A4大小的样式并已实现分页,业务上需要将这个网页生成PDF文件,并上传到服务器,后续会将这个文件发送给客户(这里不考虑). 二.原来 ...

  9. 前端生成pdf文件之pdfmake.js

    转载:点击查看原文 pdfmake.js是一个简单的生成pdf文件的插件. pdfmake.js     https://files.cnblogs.com/files/s313139232/pdfm ...

  10. Itext生成pdf文件

    来源:https://my.oschina.net/lujianing/blog/894365 1.背景 在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等. ...

随机推荐

  1. Cannot resolve module 'net' in stompjs

    解决方案1 stompjs 不支持客户端环境下运行需要作为开发依赖安装 npm install stompjs --save 解决方案2 webpack.config.js 增加这段 resolve: ...

  2. C#不提升自己程序的权限实现操作注册表

    1. 绪论 当我们编写了自己的C#程序,有程序自定义的文件类型时,通常希望它满足以下需求: 双击自定义文件打开自定义程序 自定义文件有着自己的图标 此时,在网上检索可以发现,大多数回答是使用Micro ...

  3. intel Pin:动态二进制插桩的安装和使用,以及如何开发一个自己的Pintool

    先贴几个你可能用得上的链接 intel Pin的官方介绍Pin: Pin 3.21 User Guide (intel.com) intel Pin的API文档Pin: API Reference ( ...

  4. 使用 Visual Studio 2022 调试Dapr 应用程序

    使用Dapr 编写的是一个多进程的程序,使用Visual Studio 调试起来可能会比较困难,因为 Visual Studio 默认只会把你当前设置的启动项目的启动调试. 好在有Visual Stu ...

  5. elementui中 分页在vue中的使用

     template中: <el-pagination background layout="prev, pager, next" :total="total&quo ...

  6. Flask 终端启动运行

    在终端启动 1.首先创建xxxx.py文件(xxxx表示创建的文件名)写入一个小app实例,例如: # 在hello.py文件下创建一个小的FLask app from flask import Fl ...

  7. Python AI小项目打包通关:Pyinstaller和Wix都用上了

    最近有个Python小项目要打个包,项目结构比较简单 main.py(主文件), 以及model_050.hdf5 (在云端训练好的AI模型) 主函数里引用了一些包,如下 需要解决的问题: 将main ...

  8. 一文告诉你AVM中设置字体的方法

    ​ avm 是一种简便的多端开发框架,可以开发APP.小程序.H5.今天学习了一下使用 avm 开发 APP 怎么设置字体,下面将经验分享给大家. 所需步骤: 1.  将需要使用的字体文件放到代码包r ...

  9. [机器学习] Yellowbrick使用笔记8-模型选择可视化

    Yellowbrick可视化工具旨在指导模型选择过程.一般来说,模型选择是一个搜索问题,定义如下:给定N个由数值属性描述的实例和(可选)一个估计目标,找到一个由特征.算法和最适合数据的超参数组成的三元 ...

  10. 聊聊Cookie、Session、Token 背后的故事

    摘要:Cookie.Session.Token 这三者是不同发展阶段的产物 本文分享自华为云社区<Cookie.Session.Token 背后的故事>,作者: 龙哥手记. 1. 网站交互 ...