前言
遇到在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的定位来代替,问题解决。