有一朋友想把网页内容变成PDF下载下来 。问我有没有好办法 。
这还真巧了 ,咱公司也有这个需求 ,就是网页生成合同 ,然后可以直接打印合同内容 。最早吧 ,就是可以直接打印就好了 。
当时为解决完美打印的问题 ,挺费劲的 ,当时第三方插件还有BUG(当然把解决放给发给作者了 ,作者早已经修复了) ,正经反复折腾了好一阵子 。
就留了篇帖子《VUE实现HTML页面局部内容的打印(print.js) ,出现多打印一个空白页的问题》记录一下当时踩的坑,也希望能帮到更有需要的人 。
后来校区门店想要可以选择 ,要么直接打印 ,要么保存PDF,以备日后存档和打印 。
这次比较顺利 ,至少没怎么采坑 ,直接就搞定了 。借着这次机会,也简单整理下 ,希望可以帮助有需要的人吧 。
简单步骤如下:
一 、先下载JS文件(文末附源码) ,保存到项目目录中
二 、下载两个类库
三 、引入下载的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);
})
}
}
}
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。