1. 程式人生 > >JS實現HTML轉pdf(支援高清放大及分頁)詳解

JS實現HTML轉pdf(支援高清放大及分頁)詳解

在這裡我主要講述實現思路及方法,原理大家可以自行百度,寫此文章主要是網上的很多實現方案都不能很好的支援高清放大及分頁。

首先:引入三個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、分頁不支援自動加頁碼(有解決方法請告訴我)