项目场景:

vue项目运行在移动端(企业微信聊天栏工具、企业微信浏览器、微信浏览器、外部浏览器),PC端(微信浏览器、其他厂商浏览器),利用html2canvas将页面生成图片文件,并采用jspdf将生成的图片转为pdf,并可以保存到本地。

遇到的问题

1.页面有网络路径图片导致页面网络图片的位置是空白
解决方案:先克隆需要生成pdf的动,将网络图片地址转成base64。

2.jspdf插件生成pdf,并本地直接下载,移动端微信浏览器无反应

原因分析:本地直接下载方式,可能是微信浏览器可能对于本地生成的blob文件流下载,是限制的

解决方案:采用本地生成文件流转file利用后端上传文件服务器,后端返回文件静态路径,在利用a download 下载文件,测试后pc和移动端及微信浏览器都是好使的

实现代码

1.安装插件
npm install html2canvas@1.0.0-rc.4 jspdf --save

"dependencies": {"html2canvas": "~1.0.0-rc.4",  // 锁定版本, 高版本配置项的x和y有差异问题,导致生成图片位置有便宜"jspdf": "^2.5.1",
}

2.插件引用

import html2canvas from 'html2canvas';
import jspdf from 'jspdf';
async generatePdf(){let product_proposal = this.$refs.product_proposal;let contentWidth = product_proposal.scrollWidth;let contentHeight = product_proposal.scrollHeight; //btn按钮组 上面box 外边距重合// 克隆dom 替换网络路径图片为base64let new_product_proposal = await this.handleDom(product_proposal);//将克隆dom 放置当前dom的下一层,放置操作克隆的dom时,页面有闪动new_product_proposal.style.position = 'absolute'new_product_proposal.style.top = '0'new_product_proposal.style.zIndex = '-1'//解决ios safari 页面高度大于4096 canvas最大支持4096let x = 0, y=0;if(contentHeight > 4095 && ((/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)) || /\(i[^;]+;( U;)? CPU.+Mac OS X/.test(navigator.userAgent))){let scale = 4095 / contentHeight;let newHeight = 4095;let newWidth = scale * contentWidthnew_product_proposal.style.transform = `scale(${scale})`x = (contentWidth - newWidth) / 2;y = (contentHeight - newHeight) / 2;contentWidth = newWidth;contentHeight = newHeight;}document.querySelector('.proposal-wrap').appendChild(new_product_proposal);new html2canvas(new_product_proposal,{// scale: window.devicePixelRatio*2,allowTaint: true,useCORS: true , width: contentWidth,height: contentHeight,x: x,y: y,scrollY: 0,scrollX: 0,removeContainer: true}).then((canvas)=>{//重置页面document.querySelector('.proposal-wrap').removeChild(new_product_proposal);let pageData  = canvas.toDataURL("image/jpeg", 1.0);//  l表示横版,p:纵向 (默认纵向)var pdf = new jspdf('', 'mm', [contentWidth,contentHeight]);pdf.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight);let blob = pdf.output('blob');// 上传当前模板id 分享pdf文件const formData = new FormData()let file = new File([blob],`${(new Date).getTime()}.pdf`)formData.append('file', file)formData.append('planId', planId)//调用后端上传文件接口,返回文件静态地址PDFUpload(formData).then(res=>{if(res.data.data){// 1.本地下载let link = document.createElement("a");    link.href = res.data.data;link.style.display = "none"; //a标签隐藏link.download = `${this.planName}.pdf`;document.body.appendChild(link);link.click();document.body.removeChild(link)}Toast.clear();}).catch(err=>{console.log(err);this.$toast('网络不佳,pdf生成失败,请稍后再试')})}).catch(err=>{console.log(err);this.$toast('pdf生成失败')})
}// 克隆dom 替换网络路径图片为base64
async handleDom(dom){let newDom = dom.cloneNode(true);//页面中的网络图片 配置class名为networkImglet networkImgs = newDom.querySelectorAll('.networkImg');for (let index = 0; index < networkImgs.length; index++) {//替换dom中网络路径图片为base64var srcBase64 =  await this.imgToBase64(networkImgs[index].src)networkImgs[index].src = srcBase64}return newDom;
},
//网络图片 转base64 (存在跨域的问题,需nginx配置代理)
async imgToBase64(val) {if (!val) return;var image = new Image();//截取网络路径 接口部分,匹配代理,解决跨域问题val = val.substr(val.indexOf("/img"), val.length);val = val.replace("/img", "/image");image.src = val + "?v=" + Math.random(); // 处理缓存image.setAttribute("crossOrigin", "*");var src = "";var srcPromise = new Promise((resolve, reject) => {image.onload = (e) => {var canvas = document.createElement("canvas");canvas.width = e.target.naturalWidth;canvas.height = e.target.naturalHeight;var ctx = canvas.getContext("2d");ctx.drawImage(e.target, 0, 0, canvas.width, canvas.height);var dataURL = canvas.toDataURL("image/png"); // 可选其他值 image/jpegresolve(dataURL);};});await srcPromise.then((res) => {src = res;});return src;
},

vue项目将页面生成pdf相关推荐

  1. vue项目中 页面生成pdf并下载,vue 中页面转PDF

    方法一 第一步.安装插件 // 第一个.将页面html转换成图片 npm install --save html2canvas // 第二个.将图片生成pdf npm install jspdf -- ...

  2. Puppeteer将动态html页面生成pdf(终极解决方案)

    开通掘金好几年一直没有写文章,近一年经常有朋友问我将动态的h5/vue/react/原生js 页面转成pdf,我觉得有必要写个文章,给大家提供一套经过多个项目验证的完整解决方案的思路:觉得有用可以点赞 ...

  3. 功能需求-根据页面生成pdf,pdf不需要下载只需把文件流上传到服务器

    前言 根据自身当下技术的水平和实际情况,做一个简单的记录. 需求描述 在项目中有采购合同和销售合同,这些合同新建好之后都需要有人去审核,审核通过后需要把合同生成一个pdf文件然后后端给保存起来 在项目 ...

  4. vue 项目中 自动生成 二维码

    vue 项目中 自动生成 二维码 ​ 最近在写一个vue项目,要求根据卡号可以自动生成一个二维码,并渲染在指定位置,因为第一次做类似业务,小编在网上找了找,发现了很多,具体起来主要用的就两种: QRc ...

  5. vue项目打包后生成一个配置文件可以修改打包后的服务器api地址

    vue项目打包后生成一个配置文件可以修改打包后的服务器api地址 问题描述:vue项目打包上线之后,如果要改服务器api地址,只能在源码更改然后重新打包发布,为了解决这个问题,我们可以在static增 ...

  6. vue项目通过Electron生成桌面应用

    vue项目通过Electron生成桌面应用 一.安装 1. 把electron的官方demo下载下来 2. 安装cnpm 3. npm start 启动electron 4. 修改vue项目 5. 打 ...

  7. 解决:vue项目的页面刷新之 title被重置问题

    如何解决:vue项目的页面刷新之 title被重置问题? 需求场景描述:(以title名为"个人中心"页面为例) 用户初次访问进入"个人中心"页,浏览器显示的页 ...

  8. Vue项目在页面添加水印功能

    Vue项目在页面添加水印功能 创建watermark.js文件 let watermark = {}let setWatermark = (str) => {let id = '1.234523 ...

  9. vue 项目中页面打印实现(去除页眉页脚)

    vue 项目中页面打印实现 参考文章: 13 Paged media 项目描述: 背景:框架vue.组件 element-ui,已有一个在用的后台管理系统 需求:现需在列表页面添加按钮-----打印协 ...

最新文章

  1. 对称加密与非对称加密
  2. SQL数据库学习之路(九)
  3. Android面试题目之三: 字符串转整形
  4. iOS进阶之架构设计MVVM的理解(3)
  5. 【Android 文件管理】分区存储 ( MediaStore 文件操作 )
  6. 文件内容、关键字匹配,split 和 indexOf 均可实现
  7. Ui5 tool debug - ctrl+alt+shift+s实现原理
  8. 分布式锁RedLock的java实现Redisson
  9. Qt多线程应用--QRunnable
  10. 如何创建MySQL连接器_如何安装mysql连接器
  11. HPC+AI融合发展的挑战和应对方法探讨
  12. 华为NP课程笔记4-中间系统到中间系统
  13. excel多个表格数据汇总怎么做?
  14. 使用 Visual Studio 2005中的ASP.NET 移动控件创建电子书浏览器应用程序
  15. 讯飞输入法android版升级日志,讯飞输入法Android版7.0 实力解锁三大输入难题
  16. wincc卡死、wincc运行卡在变量记录不动怎么办?WinCC在激活过程中卡住了怎么办?...
  17. python读取grib格式数据
  18. 别让用户发呆—设计中的防呆策略[转]
  19. 跟我一起写makefile
  20. 黑马程序员mysql答案_干货|MySQL常见问题及答案汇总

热门文章

  1. 《笨方法学 Python 3》31. 作出决定
  2. python 列表转换成字符串输出
  3. python人工智能抠图_python实现人工智能Ai抠图功能
  4. [20180823]IMU与db link.txt
  5. nodejs使用addon调用c/c++
  6. 时间末尾多了.000Z?
  7. Spring 项目中applicationContext.xml模板
  8. 帮我写一份情书给在一起200天的女朋友,要求1000字
  9. python自学难吗?零基础学python难吗?
  10. 计算机颜色显示器,电脑显示器怎么选,看这一篇就够了