html to pdf 輸出最漂亮的完整PDF
前陣子才介紹過透過puppeteer來將網頁儲存成PDF檔案,如果還沒看過可以參考
puppeteer docker image 中文網頁產生PDF
本篇要更新的部分有兩個
- 透過GoogleChromeLabs 提供的puppeteer as a service docker image ,可以不必再處理中文問題
- 網址直接輸出PDF的列印格式通常不會太漂亮的解決方案
參考連結
https://github.com/GoogleChromeLabs/pptraas.com
https://hub.docker.com/r/minuux/pptraas.com
首先pptraas.com直接可以支援中文輸出,沒有語系上的問題
1 |
docker run -d -p 9999:8080 minuux/pptraas.com |
完成後就可以在9999 port上使用,經過測試無論是直接輸出PDF還是畫面截圖,皆可以正確顯示中文字
接著,該如何完整個將畫面完整的輸出到PDF上而不會跑版或者背景、圖片不見之類的狀況呢?
這次,我會使用到pptraas.com所提供的兩個方法
- Render page as a PNG
- Render page as PDF
因為puppeteer所提供的page to pdf 方法是透過chrome的列印成PDF功能來實現,所以有很多狀況會變成這樣子,我們用一個例子來看
原本的畫面是這樣子
而我們直接從chrome按下列印,看到的預覽畫面就是puppeteer所產生的PDF檔
會變成這樣子
雖然可以很快的產生PDF檔,但是這樣子的內容格式根本不是我要的,接下來就來想辦法把格式保留下來產生PDF吧
首先!概念上是這樣子的,要保留樣式我們透過截圖的方式把圖片存下來,最後再將各分頁多張圖片合併輸出成PDF,當然你也可以直接截圖整頁,不做紙張分頁也是可以完整保留內容樣式的
我們從pptraas.com提供的範例中知道如何將url轉換成截圖
1 |
https://pptraas.com/screenshot?url=https://developers.google.com&size=400,400 |
重點有兩個
- size=650,850 這樣截下來的圖剛好可以塞進A4大小中,如果你有其他紙張大小需求也可以自行調整
- 網址回傳的內容是PNG圖檔內容,所以我將圖片內容透過base64_encode存下來放到cache
下面是一段laravel的範例
1 2 3 4 5 6 7 8 9 10 11 |
$url = env('PPTRAAS_URL').'screenshot?size=650,850&url=THE_URL_YOU_WANT_TO_PRINT'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $output = curl_exec($ch); curl_close($ch); $images = base64_encode($output); $uuid = Str::uuid()->toString(); //把base64 image放到快取中,並設定life time只有一分鐘 Cache::put('pdf_images_'.$uuid, $images, now()->addMinutes(1)); |
範例中,我把pptraas.com docker image 的url放在env中方便使用,並且將網址截圖後放到cache中
接著你需要另一個URL來產生剛剛截好圖的PDF,而這個頁面很簡單,只需要將cache中的圖檔拿出來放好就行了
以下是laravel blade的範例
1 2 3 4 5 6 7 8 9 10 11 |
<style> @media print { .pagebreak { page-break-before: always; } /* page-break-after works, as well */ } </style> @foreach($images as $k =>$v) <img src="data:image/png;base64,{{$v}}" style="width:800px;"> @if($k != count($images)-1) <div class="pagebreak"> </div> @endif @endforeach |
範例中呈現的是多張images轉存成一份PDF的概念,因此在每一張圖的最後加上<div class=”pagebreak”> </div>來達成換頁
但是最後一張圖就不需要再加入換頁了
最終,這個頁面會把你產生的base64圖檔全部排列出來,然後我們就可以透過這個網址來產生PDF了
1 |
https://pptraas.com/pdf?url=THE_URL_ABOVE |
透過上面的網址一樣使用curl來呼叫,你可以得到一個PDF內容
接著只要把內容return 回去就可以下載啦
1 2 3 4 5 |
$fileName = 'THE PDF NAME YOU WANT'; return response($output, 200, [ 'Content-Type' => 'application/json', 'Content-Disposition' => 'attachment; filename="'.$fileName.'.pdf"', ]); |
範例中,$output就是上面網址產生的PDF內容
以上,就可以把URL內容輕鬆轉換成PDF了