1、安装html2canvas和JsPdf

//第一个.将页面html转换成图片

npm install --save html2canvas

//第二个.将图片生成pdf

npm install jspdf --save

2、定义全局函数..创建一个htmlToPdf.js文件在指定位置.我个人习惯放在('src/components/utils/htmlToPdf')

// 导出页面为PDF格式

import html2Canvas from 'html2canvas'

import JsPDF from 'jspdf'

export default{

install (Vue, options) {

Vue.prototype.getPdf = function () {

//当点击下载pdf按钮不在页面顶部的时候会造成PDF样式不对

//首先回到页面顶部在下载PDF

let top = document.getElementById('pdfDom');

if (top != null) {

top.scrollIntoView();

top = null;

}

var title = this.htmlTitle

html2Canvas(document.querySelector('#pdfDom'), {

allowTaint: true

}).then(function (canvas) {

var pdf = new JsPDF('p', 'mm', 'a4'); //A4纸,纵向

var ctx = canvas.getContext('2d'),

a4w = 190, a4h = 277, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277

imgHeight = Math.floor(a4h * canvas.width / a4w), //按A4显示比例换算一页图像的像素高度

renderedHeight = 0;

while(renderedHeight < canvas.height) {

var page = document.createElement("canvas");

page.width = canvas.width;

page.height = Math.min(imgHeight, canvas.height - renderedHeight);//可能内容不足一页

//用getImageData剪裁指定区域,并画到前面创建的canvas对象中

page.getContext('2d').putImageData(ctx.getImageData(0, renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight)), 0, 0);

pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 10, 10, a4w, Math.min(a4h, a4w * page.height / page.width)); //添加图像到页面,保留10mm边距

renderedHeight += imgHeight;

if(renderedHeight < canvas.height)

pdf.addPage();//如果后面还有内容,添加一个空页

}

pdf.save(title + '.pdf')

}

)

}

}

}

3、在main.js中使用我们定义的函数文件。

import htmlToPdf from '@/components/utils/htmlToPdf'

Vue.use(htmlToPdf)

4、在需要的导出的页面..调用我们的getPdf方法即可.

//给自己需要导出的ui部分.定义id为"pdfDom".此部分将就是pdf显示的部分

导出PDF

在大佬封装函数基础上只是加了这句:

//当点击下载pdf按钮不在页面顶部的时候会造成PDF样式不对

//首先回到页面顶部在下载PDF

let top = document.getElementById('pdfDom');

if (top != null) {

top.scrollIntoView();

top = null;

}

5、封装到这一步,已经可以实现下载PDF了,但是,存在一个问题,页面会被切断,极其的恶心,丑到死!!!

断掉的PDF.png

如果是静态页面,可以将每个页面设置成:

//*按照我自己的代码来计算,下面的格式正好导出一页完整的PDF

.page{

width:1000px;

height:1450px;

}

但是问题在于页面里的数据通过后端动态请求过来,我们不知道文本会有多长,页面会有多长,所以只是完成page这个class还不足以让我们实现导出的功能,在百度+谷歌不成后,只能自己想办法,想到既然是切断,那就是在最小的一层嵌套上切断的,所以决定给最小的一层嵌套的代码加上一个class=”small“:

{{item.title}}

{{sonItem}}

这样我们就可以遍历我们不想分割的最小的class:small了,于是在dom渲染的时候我们执行下面的函数:

mounted() {

this.$nextTick(() => {

this.getSmall()

},

methods:{

//*重复使用可以将方法单独提取js文件中,然后在页面通过import使用,此处不再概述

//*1450是我自己的页面高度,可以声明变量

getSmall(){

let dom = document.getElementsByClassName("small");

for (var i = 0; i < dom.length; i++) {

if (

this.offset(dom[i]).top % 1450 > this.offset(dom[i + 1]).top % 1450 &&

1450 - (this.offset(dom[i]).top % 1450) < dom[i].offsetHeight

) {

dom[i-1].style.marginBottom =

1520 - (this.offset(dom[i]).top % 1450) + "Px";

}

}

});

},

offset(element) {

var pos = { left: 0, top: 0 };

var parents = element.offsetParent;

pos.left += element.offsetLeft;

pos.top += element.offsetTop;

while (parents && !/html|body/i.test(parents.tagName)) {

pos.left += parents.offsetLeft;

pos.top += parents.offsetTop;

parents = parents.offsetParent;

}

return pos;

},

}

这样当最小的节点大于剩余的高度时,添加一个marginBottom使其进入下一页,可以解决PDF导出切断的问题,但是class="small"需要手动添加,每一个最小节点都要搞一下,很麻烦,所有如果哪位大佬有更完美的解决方法,希望能够交流、指正,不胜感激。

搞到凌晨终于解决了,所以开心的一匹,睡觉!!!希望这篇文章能帮到大家,如果转发请携带链接!

html2pdf vue,VUE项目中利用html2canvas和JsPdf实现页面转PDF并保证图片不会被切断相关推荐

  1. 利用html2canvas 和 jspdf 实现html转pdf html转图片

    利用html2canvas 和 jspdf 实现html转pdf let dom = document.getElementById("pdf");html2canvas(dom) ...

  2. Vue中使用html2canvas和jspdf插件实现导出pdf(自定义html样式可带图片)并下载

    场景 若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客_若依前后端分离文档 在上面搭建起 ...

  3. canvas java 上传截图_在Vue项目中使用html2canvas生成页面截图并上传

    使用方法 项目中引入 npm install html2canvas html代码 //html代码 js代码 // 引入html2canvas import html2canvas from 'ht ...

  4. Vue项目中利用pdf.js实现pdf内容滑选文字展示与搜索功能

    Vue项目中利用pdf.js实现pdf内容滑选文字展示与搜索功能 需求:在pdf中鼠标滑动选中一段文字,将选中文字展示到input框中(pdf在iframe中) 完成效果: 关于pdf的引用:我是直接 ...

  5. Vue.JS项目中二级路由下刷新浏览器仍呈现当前路由的实现方案

    1.需求介绍: 以下介绍一下实现起来没什么疑问的需求:设备列表为一个主页,点击设备列表中的编辑按钮,进入设备信息主页面,默认打开设备配置页,点击设备状态.设备日志.固件升级,会切换下方内容. 本人对以 ...

  6. 多个html如何套用套一个头部,Vue.js项目中管理每个页面的头部标签的两种方法...

    在 Vue SPA 应用中,如果想要修改 HTML 的头部标签,如页面的 title ,我们只能去修改 index.html 模板文件,但是这个是全局的修改,如何为每个页面都设置不一样的 title ...

  7. vue.js项目中,关于element-ui完整引入、按需引入的介绍

    element-ui引入方式,简单说来有两种:完整引入.按需引入 首先谈一下npm安装element-ui的方法: cmd到项目目录,然后执行cmd命令:npm i element-ui -S稍等片刻 ...

  8. Vue.js项目中,当图片无法显示时则显示默认图片

    Vue.js项目中,当图片无法显示时则显示默认图片使用onerror方法 最近在学习Vue时,遇到了一个问题,就是从后台传过来的图片路径无效时,需要在页面显示默认图片 本人试了3种方法,2种方法失败了 ...

  9. html调用腾讯地图定位当前位置,vue web项目中调用腾讯地图API获取当前位置的经纬度...

    vue web项目中调用腾讯地图API获取当前位置的经纬度 vue web项目中调用腾讯地图API获取当前位置的经纬度 在main.js 中添加一下代码 import axios from 'axio ...

最新文章

  1. python多久能学会爬虫-上海多久可以学会python
  2. SourceTree中拉取GitLab代码时提示:Too many authentication failures“ fatal: Could not read from remote reposit
  3. 解读:在什么业务场景适合使用Redis?
  4. SAP Spartacus全局配置里和路由Route相关的配置
  5. 常常被人忽略的VC备份
  6. 从IT应用架构角度,畅谈双活数据中心容灾解决方案
  7. 怎么用Iometer测试存储性能
  8. React-router 4 按需加载的实现方式及原理(Code Splitting)
  9. 图像匹配得到精确的旋转角度
  10. 薇娅直播卖火箭,B 站酒泉发卫星,航天贴标生意凭什么?
  11. 改变世界的15个网站
  12. 去掉WPS智能生成目录中的空白行
  13. 什么是脚本语言(python脚本是什么?)
  14. 关于微软虚拟机更新后密码问题
  15. matlab仿真的英文文献,matlab 外文翻译 外文文献 英文文献 MATALAB 混合仿真平台控制算法的概述...
  16. poi导出excel 损坏_Java使用POI生成Excel文件后打不开的问题
  17. 基于正交设计的折射反向学习樽海鞘群算法
  18. FPGA Verilog视频笔记
  19. 人工智能课程期末总结
  20. 教你科学实施有氧运动

热门文章

  1. 展锐平台 Android 10.0 OTA升级开机Logo
  2. OpenMP 并行处理
  3. Python数据可视化的3大步骤,你知道吗?
  4. vue 中监听document.body.scrollTop 值总为0的解决方法
  5. 让PcShare2005vip免费
  6. strstr strcmp
  7. Java基础:方法和类详解
  8. StrictMode总结
  9. 安装Alpine操作系统
  10. iOS经典讲解之判断App是否第一次启动