javascript
JS转PDF
前端時(shí)間調(diào)研了一下js轉(zhuǎn)pdf的一些方案,做個(gè)整理。
一開始考慮前端轉(zhuǎn)還是后端轉(zhuǎn),后來想想前端可能做出來和看到的會(huì)更像一點(diǎn),所以先考慮前端的方案。
首先通過google和ata等搜到j(luò)sPDF這個(gè)庫,不過一開始看到例子都不是把html轉(zhuǎn)成pdf。
后來看了它的一些文檔,里面有個(gè)fromHTML方法,不過它不支持utf8,其github上有個(gè)issue,就我看到了有這幾個(gè)workaround:
1和2看上去比較復(fù)雜,而且也沒找到明確的從HTML轉(zhuǎn)pdf的方法,所以直接嘗試方案三,不過有興趣也可以研究一下。查看了addHTML的文檔和代碼后,寫了下面這個(gè)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);});看上去它的原理就是先把當(dāng)前頁面通過html2canvas或者rasterizeHTML庫轉(zhuǎn)成圖片,然后調(diào)用jsPDF的addimage來生成pdf。上述代碼中rstz就是控制用html2canvas還是rasterizeHTML。 不過它主要問題是不會(huì)自動(dòng)分頁,要自動(dòng)分頁的話要加上pagesplit這個(gè)選項(xiàng),但是會(huì)失真。
下面貼一些效果圖:
### html2canvas + No pagesplit
### html2canvas + pagesplit
### rasterizeHTML + No pagesplit
### rasterizeHTML + pagesplit
可以看到html2canvas在分頁時(shí)候會(huì)失真,rasterizeHTML表現(xiàn)良好。
不過在做我們這個(gè)demo的時(shí)候,我發(fā)現(xiàn)rasterizeHTML對(duì)那些復(fù)雜一點(diǎn)的css支持不是太友好,而且裝起來也比較復(fù)雜,所以最后還是用了html2canvas。然后嘗試?yán)@過分頁的bug, 最后通過多次調(diào)用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的源碼是能解決分頁問題的,不過由于時(shí)間和能力關(guān)系我還沒法解決。如果有能解決的歡迎告訴我。
另外網(wǎng)上有個(gè)類似的方案也可以參考一下.
對(duì)于后端生成pdf, 理論上也是可行的,比如這里 和 這里 不過看上去都很復(fù)雜,不如前端生成的簡(jiǎn)單。
還有就是通過phantomjs, 因?yàn)闀r(shí)間關(guān)系也沒好好研究。
總結(jié)
- 上一篇: mysql varchar 225 和
- 下一篇: Angular、Vue、React 和前