JS转PDF
前端時間調研了一下js轉pdf的一些方案,做個整理。
一開始考慮前端轉還是后端轉,后來想想前端可能做出來和看到的會更像一點,所以先考慮前端的方案。
首先通過google和ata等搜到jsPDF這個庫,不過一開始看到例子都不是把html轉成pdf。
后來看了它的一些文檔,里面有個fromHTML方法,不過它不支持utf8,其github上有個issue,就我看到了有這幾個workaround:
1和2看上去比較復雜,而且也沒找到明確的從HTML轉pdf的方法,所以直接嘗試方案三,不過有興趣也可以研究一下。查看了addHTML的文檔和代碼后,寫了下面這個js:
var pdf = new jsPDF('p','pt','a4'); var element = $("body"); element = document.getElementsByClassName("span12")[0];//element.find('.span12'); console.log(element);pdf.addHTML(element,{format: 'png',pagesplit: true,rstz: true},function() {var string = pdf.output('datauristring');pdf.save("abc.pdf");$('.preview-pane').attr('src', string);});看上去它的原理就是先把當前頁面通過html2canvas或者rasterizeHTML庫轉成圖片,然后調用jsPDF的addimage來生成pdf。上述代碼中rstz就是控制用html2canvas還是rasterizeHTML。 不過它主要問題是不會自動分頁,要自動分頁的話要加上pagesplit這個選項,但是會失真。
下面貼一些效果圖:
### html2canvas + No pagesplit
### html2canvas + pagesplit
### rasterizeHTML + No pagesplit
### rasterizeHTML + pagesplit
可以看到html2canvas在分頁時候會失真,rasterizeHTML表現良好。
不過在做我們這個demo的時候,我發現rasterizeHTML對那些復雜一點的css支持不是太友好,而且裝起來也比較復雜,所以最后還是用了html2canvas。然后嘗試繞過分頁的bug, 最后通過多次調用addHTML來避免問題。代碼如下:
var pdf = new jsPDF('p', 'pt', 'a4'); var header = document.getElementsByTagName('header')[0]; var options = { format: 'png' }; var ready = false;var sections = [document.getElementById('main-result'),document.getElementById('deep-result'),document.getElementById('other-result') ];var cy = 120;function makePDF(eles) {pdf.addHTML(header, 0, 0, options,function () {addPage(eles);}); }function addPage(eles) {if (!eles || eles.length <= 0) {ready = true;return;}var ele = eles[0];pdf.addHTML(ele, 0, cy, options,function () {cy = 0;if (eles.length > 1) {pdf.addPage();}addPage(eles.slice(1));}); }makePDF(sections);$('#onDownload').click(function () {if (ready) {pdf.save('def.pdf');} });理論上我感覺通過查看它本身addhtml的源碼是能解決分頁問題的,不過由于時間和能力關系我還沒法解決。如果有能解決的歡迎告訴我。
另外網上有個類似的方案也可以參考一下.
對于后端生成pdf, 理論上也是可行的,比如這里 和 這里 不過看上去都很復雜,不如前端生成的簡單。
還有就是通過phantomjs, 因為時間關系也沒好好研究。
總結
- 上一篇: mysql varchar 225 和
- 下一篇: Spring系列之AOP分析之为目标类挑