前段时间做vue管理端的项目,遇到这样的需求:需要前端来生成PDF文件。查找了相关的资料大致有这样的几种方案:
1.通过window.print()方法,打印当前窗口的内容。
2.通过两个插件实现,jspdf + html2canvas,本文着重说一下第二种用法。
工欲善其事必先利其器,首先我们在项目安装一下这两个插件。
npm install jspdf html2canvas --save
然后在项目的工具库封装一下,以便后续使用。
1 // 导出页面为PDF格式 2 import html2Canvas from 'html2canvas' 3 import JsPDF from 'jspdf' 4 export default { 5 install(Vue, options) { 6 Vue.prototype.getPdf = function(title, domClass) { 7 var element = document.querySelector(domClass); // 这个dom元素是要导出pdf的div容器 8 html2Canvas(element).then(function(canvas) { 9 var contentWidth = canvas.width; 10 var contentHeight = canvas.height; 11 12 //一页pdf显示html页面生成的canvas高度; 13 var pageHeight = contentWidth / 592.28 * 841.89; 14 //未生成pdf的html页面高度 15 var leftHeight = contentHeight; 16 //页面偏移 17 let position = 0; 18 //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高 19 var imgWidth = 555.28; 20 var imgHeight = 592.28 / contentWidth * contentHeight; 21 22 var pageData = canvas.toDataURL('image/jpeg', 1.0); 23 24 // var pdf = new JsPDF('', 'pt', 'a4'); 25 var pdf = new JsPDF('', 'pt', [contentWidth, contentHeight]); //不分页 26 pdf.addImage(pageData, 'JPEG', 0, 0, contentWidth, contentHeight); 27 28 //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89) 29 //当内容未超过pdf一页显示的范围,无需分页 30 // if (leftHeight < pageHeight) { 31 // pdf.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight); 32 // } else { 33 // while (leftHeight > 0) { 34 // pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight) 35 // leftHeight -= pageHeight; 36 // position -= 841.89; 37 // //避免添加空白页 38 // if (leftHeight > 0) { 39 // pdf.addPage(); 40 // } 41 // } 42 // } 43 pdf.save(title + '.pdf'); 44 }); 45 } 46 } 47 }
调用这个方法的时候最好是在$nextTick回调里使用,避免页面报奇怪的错误。有类似的需求的兄弟可以参考一下~