Web應用程序如何建立 PDF

爲了保證的可讀性,本文采用意譯而非直譯。javascript

想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!css

在一些場景下,用戶都要求一些須要的數據能以 pdf 的格式下載下來。如電子商務商店,常常須要一些報表數據來分析當月的銷售狀況。html

在本文中,將探討如何從一個web應用程序中直接生成一個PDF。這不是一個生成 PDF 庫列表,這裏主要的目的是展現不一樣生成 PDF 的方法。若是你有本身喜歡的工具或任何經驗能夠在評論中分享給咱們。前端

從HTML和CSS開始

首先考慮如何使用HTML和CSS生成PDF版本。java

CSS確實有一個處理打印CSS的規範,就是 Paged Media module。以前的文章《用CSS設計打印格式》中概述了這個規範,許多圖書出版商在他們全部的打印輸出中都使用了CSS。所以,CSS自己就有打印材料的規格,咱們固然應該可以使用它?react

用戶生成PDF的最簡單方法是直接經過的瀏覽器,選擇打印 PDF,將生成一個PDF。可悲的是,這個PDF一般並不徹底使人滿意!首先,它會有頁眉和頁腳,當你從網頁打印內容時,這些頁眉和頁腳會自動添加。固然若是你有一個樣式表,它也會根據打印樣式表進行格式化。ios

用瀏覽器直接打印的一個問題是瀏覽器對片段規範(fragmentation )的支持不足。這可能意味着你的頁面內容以不一樣尋常的方式中斷。這說明你可能沒法防止內容的次優中斷,如標題將做爲頁面上的最後一項保留,依此類推。git

此外,咱們沒法控制頁邊距框中的內容,例如 將咱們選擇的標題添加到每一個頁面或頁碼編號,以顯示頁數。 這些內容是Paged Media規範的一部分,但還沒有在任何瀏覽器中實現。github

使用瀏覽器渲染引擎打印

還有一些方法可使用瀏覽器渲染引擎將文檔打印成PDF,而不須要在瀏覽器中使用打印的菜單,而且以頁眉和頁腳結束。在我以前的的推文時,最受歡迎的選項是wkhtmltopdf,以及使用無頭ChromePuppeteer打印。web

WKHTMLTOPDF

wkhtmltopdf

接受HTML文件或多個文件,以及樣式表,並將其轉換爲PDF。它經過使用WebKit渲染引擎來實現這一點。

所以,從本質上講,這個工具與與瀏覽器打印效果是同樣的,可是,不會獲得自動添加的頁眉和頁腳。從樂觀上講,若是你有一個可用於內容的打印樣式表,那麼可使用這個工具很好地打印PDF,所以一個簡單的佈局可能打印得更好。

然而,不幸的是,因爲不支持分頁媒體規範和片斷(fragmentation)屬性,仍然會遇到與直接從web瀏覽器打印相同的問題,由於仍然使用的是瀏覽器渲染引擎進行打印。

能夠將一些標誌傳遞到wkhtmltopdf中,以便使用分頁媒體規範在缺省狀況下添加一些缺失的特性。然而,這確實須要一些額外的工做,除了寫好的 HTML 和CSS。

無頭 Chrome

另外一種是使用無頭的谷歌瀏覽器來打印 PDF。

然而,再次受到瀏覽器對 Paged Media 和 fragmentation 支持的限制。有一些選項能夠傳遞到page.pdf()函數中。與wkhtmltopdf同樣,若是有瀏覽器支持,添加了一些CSS 提供的功能。

極可能這些解決方案中的一個能夠知足你的全部需求,可是,若是發現你正在進行某種程度的任務,極可能已經達到了當前瀏覽器渲染引擎的極限,這就須要尋找更好的解決方案。

使用 JavaScript 來實現 Paged Media規範

嘗試使用JavaScript 實現Paged Media規範 - 其實是建立了 Paged Media Polyfill。 也能夠在使用 Puppeteer 提供對 Paged Media支持。 看看 paged.jsVivliostyle

使用打印用戶代理

若是你想繼續使用 HTML 和 CSS 解決方案,那麼你須要查看用於從 HTML 和 CSS 打印的用戶代理(UA),其中包含用於從文件生成 PDF 的 API。 這些用戶代理實現了Paged Media規範,而且對 CSS Fragmentation屬性有了更好的支持;,這樣能夠更好地控制輸出: 主要選擇包括:

打印UA將像web瀏覽器同樣使用CSS格式化文檔。與瀏覽器支持CSS同樣,須要查看這些UA的的文檔,以瞭解它們支持什麼。例如,Prince 在編寫本文時支持Flexbox,但不支持CSS網格佈局。當將頁面發送到正在使用的工具時,一般會使用一個用於打印的特定樣式表。與常規打印樣式表同樣,我在站點上使用的CSS並不都適合PDF版本。

爲這些工具建立樣式表與建立常規打印樣式表很是類似,可能使用不一樣的字體大小或顏色來決定顯示或隱藏什麼。而後,能夠利用分頁媒體規範( Paged Media specification)中的功能,添加腳註、頁碼等。

就從web應用程序使用這些工具而言,須要在服務器上安裝它們。這些工具的主要問題是它們很昂貴。也就是說,考慮到你能夠輕鬆地使用它們生成打印文檔,它們可能會在節省的開發人員時間中獲得很好的回報。

能夠經過API(按文檔付費)經過DocRaptor服務使用Prince。對於許多應用程序來講,這無疑是一個很好的起點,由於它看起來彷佛可使你本身的主機變得更加經濟有效,而切換的開發成本將是最小的。

一個免費的替代方案是WeasyPrint,它不像上面的工具那麼全面,但頗有可能已經知足你的需求。它沒有徹底實現全部分頁媒體規範,可是,它實現的比瀏覽器引擎更多。固然,你能夠試試!

聲稱支持從HTML和CSS轉換的其餘工具包括PDFCrowd,它大膽聲稱支持HTML5,CSS3和JavaScript。 可是,我沒法找到關於支持的確切內容的任何細節,以及是否有任何分佈媒體規範。

不使用HTML和CSS

還有許多其餘的解決方案,它們再也不使用HTML和CSS,而是要求你爲工具建立特定的輸出。下面是對應的工具:

推薦

除了基於javascript的方法(它要求打印內容建立徹底不一樣的表示形式)以外,這些解決方案的優勢在於它們是可互換的。若是你的解決方案基於調用命令行工具,並將該工具傳遞給你的HTML、CSS,可能還傳遞一些JavaScript,那麼在工具之間切換是至關簡單的。

爲了支持分佈媒體和fragmentation,Prince,Antenna House 和 PDFReactor能夠做爲首選。 做爲商業產品,他們也獲得了支持。

可是,在許多狀況下,免費工具也很適合。 若是你的的需求很是簡單,那麼wkhtmltopdf,或者基本的無頭ChromePuppeteer就能夠解決問題。

可是,若是你發現打印的結果不是本身想要的,請注意這多是瀏覽器打印的限制,而不是你作錯了什麼。若是你想要更多的頁面媒體支持,但又沒法得到商業產品,也許能夠看看WeasyPrint

但願這是一個有用的工具總結,可用幫你的web應用程序建立pdf。

工具

交流

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

https://github.com/qq44924588...

我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!

關注公衆號,後臺回覆福利,便可看到福利,你懂的。

clipboard.png

相關文章
相關標籤/搜索