前端使用html2canvas和jspdf生成pdf
参考文档:/p/56680ce1cc97
html2canvas 官网:/
1.下载插件
npm install html2canvas jspdf --save
2.功能实现方法
// 导出页面为PDF格式import html2Canvas from 'html2canvas'import JsPDF from 'jspdf'export default{install (Vue, options) {Vue.prototype.getPdf = function () {var title = this.htmlTitlehtml2Canvas(document.querySelector('#pdfDom'), {allowTaint: true}).then(function (canvas) {let contentWidth = canvas.widthlet contentHeight = canvas.heightlet pageHeight = contentWidth / 592.28 * 841.89let leftHeight = contentHeightlet position = 0let imgWidth = 595.28let imgHeight = 592.28 / contentWidth * contentHeightlet pageData = canvas.toDataURL('image/jpeg', 1.0)let PDF = new JsPDF('', 'pt', 'a4')if (leftHeight < pageHeight) {PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)} else {while (leftHeight > 0) {PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)leftHeight -= pageHeightposition -= 841.89if (leftHeight > 0) {PDF.addPage()}}}PDF.save(title + '.pdf')})}}}
3.全局引入使用
在项目主文件main.js
中引入定义好的实现方法,并注册。
import htmlToPdf from '@/components/utils/htmlToPdf'// 使用Vue.use()方法就会调用工具方法中的install方法Vue.use(htmlToPdf)
在相关要导出的页面中,点击时调用绑定在Vue原型上的getPdf方法,传入id即可
//html<div id="pdfDom"><!-- 要下载的HTML页面,页面是由后台返回 --><div v-html="pageData"></div></div><el-button type="primary" size="small" @click="getPdf('#pdfDom')">点击下载</el-button>//jsexport default {data () {return {htmlTitle: '页面导出PDF文件名'}}}
以下为遇到的问题和解决方法
问题1 在正常屏幕下,导出的pdf不清晰
开发过程中发现非2k屏导出的文件在放大查看时会发生严重的模糊现象,可通过向html2canvas的第二个参数进行参数传递解决,以下为官方给出的参数列表
我们可以通过向插件传递我们自定义的canvas来进行清晰度的调整,高分辨率屏幕注意调整scale参数,否则会造成pdf生成不全的问题
let w = element.width; // 获得该容器的宽let h = element.height; // 获得该容器的高let canvas = document.createElement("canvas");// 该处使用的是默认的A4纸张大小,也可传入元素宽高,并自行定义缩放倍数canvas.width = 595.28 * 2; // 将画布宽&&高放大两倍canvas.height = 841.89 * 2;let context = canvas.getContext("2d");context.scale(2, 2);let opts = {canvas: canvas,width: 595.28*2,height: 841.89*2,};html2Canvas(element,opts).then(function(canvas) {})
问题2,图片跨域问题
官方提供了useCORS、proxy、allowTaint三个属性来解决跨域问题,网上搜索解决方案时网友建议useCORS、allowTaint不能同时使用,会无法达成效果;个人在使用过程中上述三个配置均无法解决图片的跨域问题,最终采用了如下的解决方案,任选其一即可
与后台协商,将返回的图片数据转换为base64形式,图片可正常导出将资源部署到同一服务器,避免跨域问题的出现设置nginx允许任意来源的访问请求