在项目开发的时候,我们偶尔或者是经常会遇到一些难题,关于用js吧html页面转换成pdf也是一个难题,意思是说相当于把整个页面截下来,然后保存成pdf。
其实,能够实现html转pdf的方法还是挺多的,大概有以下几种:
1、大部分浏览器就有这个功能。然而我们客户要的可不是这个,人家要的是能够在系统中主动触发的导出为pdf功能,所以这种方案pass。
2、利用第三方工具。我找到了一种利用wkhtmltopdf这种工具来导出的方案,自己在我们的项目中试了一下,效果不好,而且对svg图片的支持也不行。pass。
3、还有一种是利用itext类后台生成java文件。但因为需要导出的这个页面是动态页面,而且直接把页面传给后台会丢失大量样式,所以还是pass。
最后没什么好的办法,只能退而求其次,想着要不先把html页面转成图片,再把图片导出为pdf。因为要支持用户导出下载,而且要保留样式,所以最好是纯js前端实现。
html转canvas的话,就用html2canvas这个js,这个网上介绍比较多了,这里就不废话了。
比较麻烦的是svg图片,直接用html2canvas无法把svg标签的内容转成canvas,最后查了一圈资料后,锁定了canvg这个js。canvg是谷歌的一个插件,可以将svg标签内容转成canvas。具体到我们的项目,还有一个难点,就是如何把glyphicons这种字体图标也转成canvas,因为在不同浏览器下对这种字体图标的支持是完全不一样的。最后找到的方法是用char code来替换这些字体图标,重新绘制成canvas。由canvas生成图片不用废话。由图片生成pdf用jspdf实现。 折腾了大半天,总算把整个流程打通了,接下来一步一步贴上代码。
第一步:把对应dom节点里所有的svg元素替换成canvas
svg2canvas: function(targetelem) {
var svgelem = targetelem.find('svg');
svgelem.each(function(index, node) {
var parentnode = node.parentnode;
//由于现在的ie不支持直接对svg标签node取内容,所以需要在当前标签外面套一层div,通过外层div的innerhtml属性来获取
var tempnode = document.createelement('div');
tempnode.appendchild(node);
var svg = tempnode.innerhtml;
var canvas = document.createelement('canvas');
//转换
canvg(canvas, svg);
parentnode.appendchild(canvas);
});
}
第二步:把glyphicons字体转成canvas。如果项目中没有用到glyphicons字体图标,可忽略这一步
glyphicons2canvas: function(targetelem, fontclassname, fontfamilyname) {
var iconelems = targetelem.find('.' + fontclassname);
iconelems.each(function(index, inconnode) {
var fontsize = $(inconnode).css("font-size");
var iconcolor = $(inconnode).css("color");
var stylecontent = $(inconnode).attr('style');
//去掉"px"
fontsize = fontsize.replace("px", "");
var charcode = getcharcodebyglyphiconsname(iconname);
var mycanvas = document.createelement('canvas');
//把canva宽高各增加2是为了显示图标完整
mycanvas.width = parseint(fontsize) + 2;
mycanvas.height = parseint(fontsize) + 2;
mycanvas.style = stylecontent;
var ctx = mycanvas.getcontext('2d');
//设置绘图内容的颜色
ctx.fillstyle = iconcolor;
//设置绘图的字体大小以及font-family的名字
ctx.font = fontsize + 'px ' + fontfamilyname;
ctx.filltext(string.fromcharcode(charcode), 1, parseint(fontsize) + 1);
$(inconnode).replacewith(mycanvas);
});
}
//根据glyphicons/glyphicon图标的类名获取到对应的char code
getcharcodebyglyphiconsname: function(iconname) {
switch (iconname) {
case("glyphicons-resize-full"):
return "0xe216";
case ("glyphicons-chevron-left"):
return "0xe225";
default:
return "";
}
}
第三步:html转canvas转图片再转pdf。
html2canvas($("#myexportarea"), {
onrendered: function(canvas) {
var imgdata = canvas.todataurl('image/jpeg');
var img = new image();
img.src = imgdata;
//根据图片的尺寸设置pdf的规格,要在图片加载成功时执行,之所以要*0.225是因为比例问题
img.onload = function() {
//此处需要注意,pdf横置和竖置两个属性,需要根据宽高的比例来调整,不然会出现显示不完全的问题
if (this.width > this.height) {
var doc = new jspdf('l', 'mm', [this.width * 0.225, this.height * 0.225]);
} else {
var doc = new jspdf('p', 'mm', [this.width * 0.225, this.height * 0.225]);
}
doc.addimage(imgdata, 'jpeg', 0, 0, this.width * 0.225, this.height * 0.225);
//根据下载保存成不同的文件名
doc.save('report_pdf_' + new date().gettime() + '.pdf');
}
},
background: "#fff",
//这里给生成的图片默认背景,不然的话,如果你的html根节点没设置背景的话,会用黑色填充。
allowtaint: true //避免一些不识别的图片干扰,默认为false,遇到不识别的图片干扰则会停止处理html2canvas
});
虽然这种方法可以将html页面转换成pdf样式,但是生成的pdf效果明显不如正常截图来的清晰,如果大家有更好的办法,欢迎指点。
相关推荐:
c#怎么将 html转换为图片或 pdf?
关于c#如何将word转换成pdf的方法汇总
使用html生成一个pdf实例代码
以上就是js实现html转成pdf的详细内容。