在这里我主要讲述实现思路及方法,原理大家可以自行百度,写此文章主要是网上的很多实现方案都不能很好的支持高清放大及分页。
首先:引入三个js插件,请自行上网百度下载,注意html2canvas.js版本太高会出现Promise未定义,本人猜测ES6高版本中可能用到ES6语法,请注意。
jspdf.min.js
html2canvas.js (本人使用的版本:html2canvas 0.5.0-alpha1)
jquery.js
说明:g(selector)是一个通用函数,主要用于获取dom元素
function g(selector){
var method = selector.substr(0,1) == '.' ?
'getElementsByClassName' : 'getElementById';
return document[method](selector.substr(1));
}
说明:这是HTML转PDF的核心代码,原理我就不说了,网上很多,就是常规的HTML转canvas再转pdf
可以参考:https://segmentfault.com/a/1190000009211079?from=singlemessage&isappinstalled=0
这面这篇文章已经很详细的介绍及解释了核心的知识点,我所做的只是完善功能,使得打印出来的pdf支持高清放大以及解决打印内容不全等情况。
function btnDownloadPageBypfd2(pdf_container){ //参数是'#pdf_container' 或 '.pdf_container',注意带前缀
$(pdf_container).addClass('pdf'); //pdf的css在下一个代码中,作用是使得打印的内容能在pdf中完全显示
var cntElem = g(pdf_container);
var shareContent = cntElem; //需要截图的包裹的(原生的)DOM 对象
var width = shareContent.offsetWidth; //获取dom 宽度
var height = shareContent.offsetHeight; //获取dom 高度
var canvas = document.createElement("canvas"); //创建一个canvas节点
var scale = 2; //定义任意放大倍数 支持小数
canvas.width = width * scale; //定义canvas 宽度 * 缩放,在此我是把canvas放大了2倍
canvas.height = height * scale; //定义canvas高度 *缩放
canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
html2canvas(g(pdf_container), {
allowTaint: true,
taintTest: true,
canvas: canvas,
onrendered: function(canvas) {
var context = canvas.getContext('2d');
// 【重要】关闭抗锯齿
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
var imgData = canvas.toDataURL('image/jpeg',1.0);//转化成base64格式,可上网了解此格式
var img = new Image();
img.src = imgData;
img.onload = function() {
img.width = img.width/2; //因为在上面放大了2倍,生成image之后要/2
img.height = img.height/2;
img.style.transform="scale(0.5)";
console.log("img.width"+img.width);
console.log("this.width="+this.width);
console.log("this.height="+this.height);
/*if (this.width > this.height) {//此可以根据打印的大小进行自动调节
var doc = new jsPDF('l', 'mm', [this.width * 0.255, this.height * 0.225]);
} else {
var doc = new jsPDF('p', 'mm', [this.width * 0.255, this.height * 0.225]);
}
doc.addImage(imgData, 'jpeg', 10, 0, this.width * 0.225, this.height * 0.225);
doc.save('report_pdf_' + new Date().getTime() + '.pdf');*/
/****分页******/
var pageHeight = 841.89;//一页高度
var leftHeight = height * 0.75;//未打印内容高度
var position = 0;//页面偏移
var imgWidth = width;
//var imgHeight = 841.89;
var imgHeight = height;
console.log("imgWidth="+imgWidth);
console.log("imgHeight="+imgHeight);
var doc = new jsPDF('p', 'pt', 'a4');
if(pageHeight >= leftHeight){//不需要分页,页面高度>=未打印内容高度
console.log("不需要分页");
doc.addImage(imgData, 'jpeg', 35, 0, imgWidth*0.75, imgHeight*0.75);
}else{//需要分页
console.log("需要分页");
while(leftHeight>0){
console.log("position="+position);
console.log("leftHeight="+leftHeight);
doc.addImage(imgData, 'JPEG', 35, position, imgWidth*0.75, imgHeight*0.75);
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if(leftHeight > 0){
console.log("添加空白页");
doc.addPage();
}
}
}
doc.save('report_pdf_' + new Date().getTime() + '.pdf');//保存为pdf文件
}
},
background: "#fff", //一般把背景设置为白色,不然会出现图片外无内容的地方出现黑色,有时候还需要在CSS样式中设置div背景白色
});
$('#pdf_container').removeClass('pdf');
}
//这里的pdf类的作用是使得要转化的div永远能在pdf中从左到右显示出来,防止出现转化后内容不全等情况
.pdf{
position:fixed;
left: 0;
top: 0;
}
上面方法基本解决了大部分的情况,多数情况下只要设置一下参数,自己调一调就可以直接用了。
缺点:
1、分页不支持自动加页码(有解决方法请告诉我)