在許多生成報表的時候須要咱們後臺做出動態的數據,並渲染到前端生成pdf格式,Excel格式的各類報表,可是瀏覽器自帶的生成pdf功能,windows系統的ctrl+p鍵就能徹底搞定這一需求,但對客戶來講,這種體驗極差,確定是不行的,有好幾種方法將html生成pdf格式,每一種方法都有本身的優缺點,javascript
先簡單談一談第一種比較簡單的jsPDF,代碼徹底有javascript就夠了,不須要後臺,可是無論哪種都須要頁面前端代碼寫的表準規範,不那麼亂套就行,css
jsPDF:直接上代碼:html
<!DOCTYPE html> <html> <head> <title>jsPDF</title> <meta charset="utf-8"> <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> <script type="text/javascript"> function htmltopdf() { var target = document.getElementsByClassName("report")[0]; target.style.background = "#ffffff"; html2canvas(target, { 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 = 570.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("test.pdf"); } }) } </script> <style type="text/css"> .report{width: 80%;height: 500px;margin: auto;} </style> </head> <body> <div class="report"> <h2>jspdf生成PDF</h2> <button onclick="htmltopdf()">點擊生成pdf</button> <table border="1" cellspacing="0"> <thead> <tr> <th align="center">調研對象</th> <th align="center">優勢</th> <th align="center">缺點</th> <th align="center">分頁</th> <th align="center">圖片</th> <th align="center">表格</th> <th align="center">連接</th> <th align="center">中文</th> <th align="center">特殊字符、樣式</th> <th align="center">導出樣例</th> <th align="center">備註</th> </tr> </thead> <tbody><tr> <td align="center">jsPDF</td> <td align="center">一、整個過程在客戶端執行(不須要服務器參與),調用簡單</td> <td align="center">一、生成的pdf爲圖片形式,且內容失真</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">不支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center"></td> <td align="center"></td> </tr> <tr> <td align="center">iText</td> <td align="center">一、功能基本能夠實現,比較靈活二、生成pdf質量較高</td> <td align="center">一、對html標籤嚴;格,少一個結束標籤就會報錯;二、後端實現複雜,服務器須要安裝字體;三、圖片渲染比較複雜(暫時還沒解決)</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center"></td> <td align="center"></td> </tr> <tr> <td align="center">wkhtmltopdf</td> <td align="center">一、調用方式簡單(只需執行一行腳本);二、生成pdf質量較高</td> <td align="center">一、服務器須要安裝wkhtmltopdf環境;二、根據網址生成pdf,對於有權限控制的頁面須要在攔截器進行處理</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center">支持</td> <td align="center"></td> <td align="center"></td> </tr> </tbody></table> </div> </body> </html>
網頁呈現下面樣式:前端
點擊按鈕執行js生成:java
但這種方式有很大的缺點,分頁時會出現比較大的瑕疵,總體像素低,看起來不是特別的清晰canvas
總體來講是截取的部分html代碼,下圖獲取元素爲要截取的div,必須與後邊保持一致,此外還需外部導入js,這種方式使用canvas至關於將html頁面截屏保存成圖片放入pdf當中,謹慎使用。windows
下篇繼續寫wkhtmltopdf吧後端