html转pdf的那些事

各种文档,文章,报表,报告等这种依靠数据生成的资料,一般用户都会提出需要导出的功能。

导出一般要求导出word,Excel和pdf,这里谈一下测试过多种html转pdf的心得。(html转word目前没发现特别好用的工具包,目前我的实现的方式是apache poi ,但是确实不太好用,样式是自己解析的,在处理附加图片的时候真心很费劲)。

html转pdf 之 itext

itext是开源的java处理pdf文件的工具包,

com.itextpdf.html2pdf.HtmlConverter;

在该包下将html转pdf的接口,但是实际测试效果不佳,和页面的显示效果出入比较大。当然它也不是这篇文章的重点。

html转pdf 之  html2canvas + jspdf

这是我探究了几种实现方式后的最佳方案(对于我是最佳,技术选择只有合不合适,没有对错)。

注:是jspdf 不是pdf.js

实现的思路如下:

  1. 将html转化为canvas
  2. 将canvas转化为图片
  3. 将图标添加到pdf文件中
  4. 输出pdf 文件

优势:

  1. 不经过后端,减轻了后端压力
  2. 转化后的pdf文件和预想效果最接近(导出默认为A4,文章样式宽高如果没有调节好,不见得就一致)
  3. 前端很多漂亮的报表,图例,图标等资源可以直接使用,并且效果渲染的非常好。
  4. 支持分页。(jspdf 支持分页,但是分页规则需要自己制定)
  5. 结合markdown编辑器,富文本编辑器或者freemarker模板可以更好的输出优质的pdf。

劣势:

  1. 兼容性,canvas对IE兼容性不是很好,这个是比较尴尬的(我目前不考虑IE低版本)
  2. 存在pdf文件失真的问题(最终是将图片加入到pdf文件中,图片是会失真的,解决方案就是将html转化为图片的时候做放大处理,我这里是放大了3倍)
  3. 在html转canvas的时候又是需要处理一下。
  4. 签章之类的目前无法处理。(jspdf有些方面不如itext强大的)

下面是个实例,做完后会开源所有代码(使用vue开发一个文档系统)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<!-- <script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script> -->
		<script src="js/html2canvas.js"></script>
		<script src="https://cdn.bootcss.com/jspdf/1.5.3/jspdf.min.js"></script>
		<script src="js/jquery.min.js"></script>
		<script src="js/echarts.min.js"></script>

		<div id="capture" style="background: #FFFFAA;height: 350px;width: 600px;">
		 <div id="main" style="width: 400px; height: 300px;"></div>
		</div>
		<div id="ddddd">
			<img id="imgContent" />
		</div>
		<script>
			 var myChart = echarts.init(document.getElementById('main'));
			var option = {
				xAxis: {
					type: 'category',
					data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
				},
				yAxis: {
					type: 'value'
				},
				series: [{
					data: [820, 932, 901, 934, 1290, 1330, 1320],
					type: 'line'
				}]
			};
			  myChart.setOption(option);
		</script>
		 <script>
			var w = $('#capture').width();
			var h = $('#capture').height();
			var type = "bmp";
			console.log(w + "  -------------------------- " + h);
			var obj =  document.getElementById('capture');;
			var doc = window.document;
		    var width = obj.offsetWidth; 
		    var height = obj.offsetHeight;
			console.log(width + "    "+ height)
		    var canvas = document.createElement("canvas"); 
		    var context = canvas.getContext("2d");
		    var scale = 3; 
		
		    canvas.width = width * scale;
		    canvas.height = height * scale;
		    		    
		    canvas.getContext("2d").scale(scale, scale); 
			
				var opts = {
					scale: scale, 
					canvas: canvas, 
					logging: true, 
					width: width, 
					height: height ,
				};
				
				var doc = new jsPDF();
				setTimeout(function(){
					
						html2canvas(document.querySelector("#capture"),opts).then(_canvas => {
						 $imgs = document.getElementById('ddddd');
						//$imgs.appendChild(Canvas2Image.convertToImage(canvas, w, h, type))
						 var image = _canvas.toDataURL("image/jpeg",1.0);
					
						 var scalePix = 210/w ;
						 var heightPdf = h * scalePix;
						 console.log("  ::: " + heightPdf);
						doc.addImage(image, type, 5, 5, 200, heightPdf);
						doc.save('hello.pdf')
						document.body.appendChild(_canvas)
					}); 
				},2000)

		</script>
		
	</body>
</html>

html2canvas  

github https://github.com/niklasvh/html2canvas/

官网:http://html2canvas.hertzen.com/

jspdf 

github https://github.com/MrRio/jsPDF 

官网:http://mrrio.github.io/ 

猜你喜欢

转载自blog.csdn.net/qq_26462567/article/details/86679110