jsPDF(高清),html导出多页pdf(分享)

2023-11-15

前言

遇到在html导出PDF的需求,在csdn找了很多关于PDF导出功能的文章,介绍了jsPDF、iText和wkhtmltopdf三种方式。
其中iText的使用对于中文还需要导入特定字体包,wkhtmltopdf需要配置服务器环境,综合考虑,选择了最简单的jsPDF。
很多文章都说jsPDF内容模糊、导出效果失真。谷歌搜了挺久,后来看到这一篇文章:
[转](https://blog.csdn.net/qq_36706878/article/details/111289963)

需要添加canvas画布元素,以及设定对应的尺寸;其中html2canvas的属性dpi的赋值倒显得不是很要紧(注释后,几乎不影响清晰度)。

只截取封面做为对比,修改前效果:
在这里插入图片描述
新增canvas后:
在这里插入图片描述

首先,引入js包:

<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
<script src="https://cdn.bootcss.com/jspdf/1.3.4/jspdf.debug.js"></script>

导出pdf函数代码如下:

//pdf
htmltopdf=function() {
   	var element = $(".ui-pdf-content"); // 这个dom元素是要导出pdf的范围div
   	var w = element.width();    // 获得该容器的宽
   	var h = element.height();    // 获得该容器的高
   	var offsetTop = element.offset().top;    // 获得该容器到文档顶部的距离
   	var offsetLeft = element.offset().left;    // 获得该容器到文档最左的距离
   	var canvas = document.createElement("canvas");
   	var abs = 0;
   	var win_i = $(window).width();    // 获得当前可视窗口的宽度(不包含滚动条)
   	var win_o = window.innerWidth;    // 获得当前窗口的宽度(包含滚动条)
   	if(win_o>win_i){
   		abs = (win_o - win_i)/2;    // 获得滚动条长度的一半
   	}
   	canvas.width = w * 4;    // 将画布宽&&高放大4倍
   	canvas.height = h * 4;
   	var context = canvas.getContext("2d");
   	context.scale(4, 4);
   	context.translate(-offsetLeft-abs,-offsetTop);
		//这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此translate的时候,要把这个差值去掉
   	html2canvas(element, {
   		allowTaint: true,
   		taintTest: true,
   		canvas: canvas,
   		dpi: 172,//导出pdf清晰度
   		onrendered: function(canvas) {
   			var contentWidth = canvas.width;
   			var contentHeight = canvas.height;
   			//一页pdf显示html页面生成的canvas高度;
   			var pageHeight = contentWidth / 592.28 * 841.89;
   			//未生成pdf的html页面高度
   			var leftHeight = contentHeight;
   			//页面偏移
   			var position = 0;
   			//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
   			var imgWidth = 595.28;
   			var imgHeight = 592.28/contentWidth * contentHeight;
   			var pageData = canvas.toDataURL('image/jpeg', 1.0);
   			var pdf = new jsPDF('', 'pt', 'a4');
    		//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
    		//当内容未超过pdf一页显示的范围,无需分页
   			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();
   					}
   				}
   			}
   			pdf.save('能耗分析报告'+'.pdf');
   		}
       });
}

样式细节:如果css采用的是transform: translateX(-50%)来实现水平居中(比如我这里封面上的方框,如下图红框所圈),会导致PDF每一页正中位置都有这个方框。
在这里我取消transform: translateX(-50%),用position: absolute的定位来代替,问题解决。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jsPDF(高清),html导出多页pdf(分享) 的相关文章