昨天搞了個前端html轉pdf的功能。略有所收,踩了一些坑,所以做些記錄,為后來的兄弟做些提示。經過一番調研發現html導出pdf一般有這幾種方式,各有各有優缺,下面簡單介紹。
一、通過jsPdf實現
此種方案可以看昨天寫的博客:jsPDF將html頁面生成pdf文件的前端解決方案及html2canvas如何真正解決跨域圖片的問題
主要就是利用html2canvas和jsPDF生成pdf文件,對於不分頁的文件比較好,如果對於需要分頁的文件,則不大適合。當然對於確實需要分頁pdf文件,下面這個方法通過打印預覽實現,也是不錯的選擇。
二、通過打印預覽實現
通過打印預覽來實現導出pdf並不是什么稀奇事,一般瀏覽器(Chrome)在頁面手動Ctrl + P
都能將當前頁進行打印預覽。在打印預覽的時候我們更改打印方式,選擇將頁面保存為PDF
即可實現頁面保存為PDF的功能。
比如我們在谷歌進行Ctrl + P
就可以看到這個功能。而且對pdf分頁還處理的挺好的。
程序中實現這個則要靠下面這個方法來實現:
window.print(); // 在控制台執行print()也能看到上面打印預覽的效果
當然能導出PDF只是主要需求,我們還有一些其他的需求
- 只想將頁面的一
部分導出為PDF
- 我們想導出的PDF是
A4紙大小
- 我們想導出的PDF是
豎着的
- 我們還想調整導出PDF的
樣式等等
這些需求通過在對css中媒體查詢
的定義就可以實現。具體可以看下這篇博客:通過CSS控制window.print打印樣式淺析
@media print { @page { size: A4 portrait; // A4大小 縱向
} .other-ele { // 打印時將不需要的元素隱藏
display: none; } .pdf-title { // 只在打印時候顯示的元素
display: block; } .panel-sm { // 打印時候改變某些元素的樣式
margin: 0; border: 1px solid #bce8f1; } }
需要提醒的是:如果要改變原有樣式,最好是在元素上新加一個
class或者id來寫,而不是在原有class上寫。
比如有這樣一個元素
<h1 class="title">我是PDF標題</h1>
// 打印時候要把這個字體大小設置成18px的話,我們不能這么寫
@media print{ .title { // not work
font-size: 18px; } }
這樣寫是不起作用的。想要生效得在元素上新加一個class類寫
<h1 class="title title-print">我是PDF標題</h1> @media print{ .title-print { font-size: 18px; } }
經過實踐,這樣寫才可以生效。
有人可能覺得這樣寫略有麻煩,別擔心,總有人會讓麻煩的事情變得簡單,基於window.print()
有人封裝了一些插件:
PrintArea可以簡單的實現部分區域打印,他的原理是通過把要打印的部分放入一個新的iframe然后觸發這個iframe的print。這個插件不太穩定,會出現空白,請酌情使用。
jQuery.print比上面的稍微好點,支持了一些css方面的東西,具體看這個jQuery.print中文配置參數
這種方法前端實現,靈活簡單,而且在頁面還原上是很好
的,生成pdf的過程不需要自己操心
,頁面樣式還可控
,可以說是非常不錯的。但是因為瀏覽器對print
方法的支持不一
,所以目前也就只能在Chrome上用用。另外,這個方法還需要用戶點一下保存按鈕,用戶體驗上也不太好
。
三、后端導出pdf
iText
、wkhtmltopdf
、prince
這三個都是后端生成pdf的工具。這三個都沒有node api。
想看具體的比較可以參考這篇文章html頁面導出為pdf(jsPDF、iText、wkhtmltopdf)。