VUE框架中实现HTML页面(局部)内容转PDF下载

  • VUE框架中实现HTML页面(局部)内容转PDF下载已关闭评论
  • 137 次浏览
  • A+
所属分类:Web前端
摘要

有一朋友想把网页内容变成PDF下载下来。问我有没有好办法。这还真巧了,咱公司也有这个需求,就是网页生成合同,然后可以直接打印合同内容。最早吧,就是可以直接打印就好了。

有一朋友想把网页内容变成PDF下载下来。问我有没有好办法。

这还真巧了,咱公司也有这个需求,就是网页生成合同,然后可以直接打印合同内容。最早吧,就是可以直接打印就好了。

当时为解决完美打印的问题,挺费劲的,当时第三方插件还有BUG(当然把解决放给发给作者了,作者早已经修复了),正经反复折腾了好一阵子。

就留了篇帖子《VUE实现HTML页面局部内容的打印(print.js),出现多打印一个空白页的问题》记录一下当时踩的坑,也希望能帮到更有需要的人。

后来校区门店想要可以选择,要么直接打印,要么保存PDF,以备日后存档和打印。

这次比较顺利,至少没怎么采坑,直接就搞定了。借着这次机会,也简单整理下,希望可以帮助有需要的人吧。

 

简单步骤如下:

一、先下载JS文件(文末附源码),保存到项目目录中

二、下载两个类库

cnpm install --save html2canvas cnpm install jspdf --save

三、引入下载的htmlToPdf.js文件,在_main.js文件中导入

import htmlToPdf from '../libs/js/htmlToPdf.js';
Vue.use(htmlToPdf);

四、直接使用 this.getPdf() 调用函数即可

// nodeName:节点名称(要打印的内容) // fileName:要生成的pdf文件名,不包含(.pdf)扩展名 // scale:PDF文字的清晰度 // style:自定义样式,根据需要,可以传入样式对要打印的对象进行一定的设定 let fileName = '合同' + EUtils.dateFormat(new Date(), 'yyyymmddhhiiss');// 生成pdf文件名,格式:合同年月日时分秒 this.getPdf('#auditionOrder', fileName);// nodeName, fileName, scale, style 此方法一共四个参数,一般前两个参数基本就满足绝大部分需求了

看上去够简单了吧?对于这次问题的解决,相对的,前期确实比较顺利,但是生成的PDF文件的内容样式调整确实还需要耗费精力去精雕细琢。

当然,这就没有技术难度了,就是一个经验和耐心的活了,不在这里描述了。

 

附htmlToPdf.js源码

/**  * 通用html转PDF文件  *   * 需要先下载两个插件,才可以正常使用  * cnpm install --save html2canvas  * cnpm install jspdf --save  *   * 在需要使用的地方,直接调用this.getPdf(nodeName, fileName, scale, style);  * nodeName,页面中需要转成PDF文件的内容部分定义id属性,id属性值  * fileName,要生成的pdf文件名,不包含(pdf)扩展名  * scale,PDF文字的清晰度  * style,自定义样式,根据需要,可以传入样式对要打印的对象进行一定的设定  * 例如:this.getPdf('#nodeId' 'PDF文件名');  */ /* eslint-disable */ import html2Canvas from 'html2canvas'; import JsPDF from 'jspdf';  export default {     install(Vue, options) {         Vue.prototype.getPdf = function(nodeName, fileName, scale, style) {             // 导出之前先将滚动条置顶,不然会出现数据不全的现象             window.pageYOffset = 0;             document.documentElement.scrollTop = 0             document.body.scrollTop = 0              // loading提示信息             this.$Message.config({top:500});             var downloadPdfMsg = this.$Message.loading({                 content : 'PDF文件生成中...',                 duration : 0,             });             // 要转化的数据             var html2Pdf = nodeName ? document.querySelector(nodeName) : document.body;// 要转换的数据(没有传入指定节点,则默认转换整个页面)                          if (style) { // 如果传入自定义样式                 html2Pdf.style.cssText = style;             }               // 参数配置             var opts = {                 allowTaint: true,//允许加载跨域的图片                 taintTest: true, //检测每张图片都已经加载完成                 scale: scale || 3, // 添加的scale 参数                 logging: false, //日志开关,发布的时候记得改成false                 useCORS: false             };             html2Canvas(html2Pdf, opts).then((canvas) => {                 var contentWidth = canvas.width;                 var contentHeight = canvas.height;                 var pageHeight = contentWidth / 592.28 * 841.89;//一页pdf显示html页面生成的canvas高度                 var leftHeight = contentHeight;                 var position = 0;                 var imgWidth = 595.28;// A4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高                 var imgHeight = 592.28 / contentWidth * contentHeight;                   var pageData = new Image();                 //设置图片跨域访问                 pageData.setAttribute('crossOrigin', 'Anonymous');                   setTimeout(() => {                     pageData = canvas.toDataURL('image/jpeg', 1.0);                     var 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 -= pageHeight;                             position -= 841.89;                             if (leftHeight > 0) {                                 PDF.addPage();                             }                         }                     }                     setTimeout(downloadPdfMsg, 500);// 关闭loading提示                     PDF.save((fileName ? fileName : new Date().getTime()) + '.pdf');// 如果没有传入要生成的文件名,则默认使用当前时间戳作为文件名                 }, 1000);             })         }     } }