1. 程式人生 > >最好用Html轉pdf的工具——wkhtmltopdf

最好用Html轉pdf的工具——wkhtmltopdf

實習時公司需要把一些html頁面中的部分內容生成pdf檔案,然後我就找一些用php把html頁面圍成pdf檔案的類。方法是可謂是找了很多很多,什麼html2pdf,pdflib,FPDF這些都試過了,但是都沒有達到我要的求(主要是不能解決中文亂碼的問題以及樣式排版的問題)。

pdflib,FPDF 這兩個方法是需要編寫程式去生成pdf的,就也是講不支援直接把html頁面轉換成pdf;html2pdf這個雖然可以把html頁面轉換成pdf文 件,但是它只能轉換一般簡單的html程式碼,如果你的html內容要的是通過後臺新聞編輯器排版的那肯定不行的。

糾結了半天,什麼百度,谷歌搜尋都用了,搜尋了半天,功夫不負有心人,終於找到一個非常好用的方法了,下面就隆重介紹。

它就 是:wkhtmltopdf,wkhtmltopdf可以直接把任何一個可以在瀏覽器中瀏覽的網頁直接轉換成一個pdf,首先說明一下它不是一個php 類,而是一個把html頁面轉換成pdf的一個軟體(需要安裝在伺服器上),但是它並不是一個簡單的桌面軟體,而且它直接cmd批處理的,使用php中的 shell_exec()函式就可以呼叫它。下面就介紹如何用php+js+html來讓它生成pdf檔案的方法(不過有個缺陷就是他需要在伺服器端生成一個快取檔案,如果你使用thinkphp框架的話就可以將其快取檔案放在runtime 資料夾中暫存就行)。

一,下載並安裝wkhtmltopdf
1、下載地址:

http://wkhtmltopdf.org/downloads.html 如圖:
這裡寫圖片描述
2、上面有各種平臺下安裝的安裝包,英文不好的直接谷歌翻譯一下。下面以 windows7平臺上使用舉例,我的下載的是stable(穩定版)的wkhtmltopdf-0.12.3.2-installer.exe這個版本,我在win7、win8 32位和64位以及win-sever上安裝測試都沒有問題的,系統時幾位就下載幾位的安裝包。下載好以後直接安裝就可以了,注意安裝路徑要知道,下面會用到的。
這裡寫圖片描述
3、安裝好以後需要在系統環境變數變數名為”Path”的後新增:;D:\wkhtmltopdf\bin 也就是你安裝的目錄。安裝好以後重啟電腦。
下圖是如何設定環境變數:

開啟我的電腦右鍵屬性

開啟我的電腦右鍵屬性

點選高階系統設定

點選高階系統設定

找到高階裡面點選環境變數

找到高階裡面點選環境變數

找到系統變數中的path,點選編輯,將剛剛的安裝位置複製到最後,記得前面加一個分號哦!

找到系統變數中的path,點選編輯,將剛剛的安裝位置複製到最後,記得前面加一個分號哦!
這裡寫圖片描述

二,測試使用效果
直接在cmd裡輸入:wkhtmltopdf http://www.baidu.com/ D:website1.pdf(注意中間有空格哈)
第一個是:執行軟體名稱(這個是不變的) 第二個是網址 第三個是生成後的路徑及檔名。回車後是不是看生一個生成進度條的提示呢,恭喜您已經成功了,到你的生成目錄裡看看是不是有一個剛生成的pdf檔案呢。
操作方法:1、windows鍵+r開啟搜尋框,輸入cmd,點選確定

這裡寫圖片描述

2、直接在cmd裡輸入:wkhtmltopdf http://www.baidu.com/ D:website1.pdf(注意中間有空格哈)

這裡寫圖片描述

3、點選回車後,會看到一個進度條,然後就提示轉換成功!

這裡寫圖片描述

4、之後在相應位置(即剛剛設定的D盤)中會發現多了一個Pdf檔案,就說明成功了

這裡寫圖片描述

三,php裡呼叫
php裡呼叫是很簡單的,用shell_exec這個函式就可以了,如果shell_exec函式不能用看看php.ini裡是否補禁用了(找到php.ini中的shell_exec函式,取消註釋就可以了,一般都是可以直接用的)。簡單舉例:

<?php shell_exec("wkhtmltopdf http://www.shwzzz.cn/ 1.pdf") ?>

你會發現在你php檔案的同級目錄中會生成一個1.pdf的檔案

下面程式碼舉例介紹如何在網站開發中使用它:主要功能是擷取網頁的部分傳遞到php中處理成pdf文件
html頁面程式碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <script src="js/jquery-2.1.4.min.js"></script>
  <link rel="stylesheet" href="css/common.css">
  <link rel="stylesheet" href="css/myCenter.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>霍蘭德職業測試</title>
</head>
<body>
<!--startprint-->
<div class="right5"> 
        <div class="right_top"  style="background-image:url(images/right-di.png);">
            <h3>霍蘭德測試報告</h3>
        </div>
        <div class="print">
            <input type="button" value="下載報告"  id="down" class="print_btn">
        </div> 
        <div class="Hollander">
                <h6>MBTI測試結果:ESTJ</h6>
                <div id="chart"></div>
                <p>約翰·霍蘭德(John Holland)是美國約翰·霍普金斯大學心理學教授,美國著名的職業指導專家。霍蘭德以職業興趣理論為基礎,先後編制了職業偏好量表(VocatIonaI Preference lnventory)和自我導向搜尋表(Self-directed Search)兩種職業興趣量表,霍蘭德力求為每種職業興趣找出兩種相匹配的職業能力。興趣測試和能力測試的結合在職業指導和職業諮詢的實際操作中起到了促進作用。</p>
        </div>   
        <table class="tbl1">
         <tbody>
            <tr node-type="toolBar">
                <td class="tbl11">領導模式:</td>
                <td class="tbl12">
                    <p>①直接領導,快速管理 ②運用過去經驗解決問題 ③直接、明確地識別問題的核心 ④決策和執行決策非常迅速 ⑤傳統型領導,尊重組織內部的等級和組織獲得的成就</p>
                </td>
              </td>
            </tr>
            <tr node-type="toolBar">
                <td class="tbl11">領導模式:</td>
                <td class="tbl12">
                    <p>①直接領導,快速管理 ②運用過去經驗解決問題 ③直接、明確地識別問題的核心 ④決策和執行決策非常迅速 ⑤傳統型領導,尊重組織內部的等級和組織獲得的成就</p>
                </td>
              </td>
            </tr>
            <tr node-type="toolBar">
                <td class="tbl11">領導模式:</td>
                <td class="tbl12">
                    <p>①直接領導,快速管理 ②運用過去經驗解決問題 ③直接、明確地識別問題的核心 ④決策和執行決策非常迅速 ⑤傳統型領導,尊重組織內部的等級和組織獲得的成就</p>
                </td>
              </td>
            </tr>
            <tr node-type="toolBar">
                <td class="tbl11">領導模式:</td>
                <td class="tbl12">
                    <p>①直接領導,快速管理 ②運用過去經驗解決問題 ③直接、明確地識別問題的核心 ④決策和執行決策非常迅速 ⑤傳統型領導,尊重組織內部的等級和組織獲得的成就</p>
                </td>
              </td>
            </tr>
            <tr node-type="toolBar">
                <td class="tbl11">適合報考專業:</td>
                <td class="tbl12">
                    <a><span>專業定位卡介紹>></span></a>
                </td>
              </td>
          </tr>
       </tbody>
     </table>    
</div>
<!--endprint-->
    <form action="pdf.php" method="post" name="hld_res" id="hideform">
      <input type="hidden" id="hide_content" name="html"/>
    </form>  
</body>
  <script>
    $(function () {
      //獲取需要傳遞的Html程式碼 通過<!--startprint--><!--endprint-->擷取
      bdhtml=window.document.body.innerHTML; 
      sprnstr="<!--startprint-->"; 
      eprnstr="<!--endprint-->"; 
      prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17); 
      prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr)); 
      //將獲取的html程式碼新增到隱藏域中傳給php檔案處理
      $("#hide_content").val(""+prnhtml+"");
    } );   

    $("#down").click(function(){
      $("#hideform").submit();
    }); 

  </script>
</html>

php頁面:

<?php
    //轉成pdf
        $html=$_POST['html'];
        //Turn on output buffering
        ob_start();
        $html='
        <link rel="stylesheet" href="css/common.css">
        <link rel="stylesheet" href="css/myCenter.css">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'.$html;
        //這兒可以引入生成的Html的樣式表  路徑可以是絕對路徑也可以是相對路徑,也可以把樣式表文件複製到臨時html檔案的目錄下 即這兒的demo檔案目錄下(預設) 也可以直接把樣式寫在html頁面中直接傳遞過來
        //$html = ob_get_contents();
        //$html=$html1.$html;
        $filename = "hld";

        //save the html page in tmp folder  儲存的html臨時檔案位置 可以是相對路徑也是可以是絕對路徑 下面用相對路徑
        file_put_contents("{$filename}.html", $html);

        //Clean the output buffer and turn off output buffering
        ob_end_clean();

        //convert HTML to PDF
        shell_exec("wkhtmltopdf -q {$filename}.html {$filename}.pdf");
        if(file_exists("{$filename}.pdf")){
            header("Content-type:application/pdf");
            header("Content-Disposition:attachment;filename={$filename}.pdf");
            echo file_get_contents("{$filename}.pdf");
            //echo "{$filename}.pdf";
        }else{
            exit;
        }
     ?>

點選頁面中的下載按鈕,

這裡寫圖片描述

是不是彈出一個下載提示,開啟下載的pdf,是不是和網頁上的樣式一模一樣呢,

這裡寫圖片描述
這裡寫圖片描述

再開啟Php檔案中的檔案儲存位置,看看是不是多了兩個臨時檔案呢?
這兩個臨時檔案在哪兒,你的css就得在哪兒,或者你直接使用相對路徑,引用其他檔案中的css樣式也可以的,最簡單的就是把css樣式直接寫在要轉成pdf的html頁面中。
這裡寫圖片描述

如果存在樣式沒有,那就是你的樣式路徑沒有寫對,在檢查一下就可以了!

四,解決分頁問題
wkhtmltopdf 很好用,但也有些不盡人意。就是當一個html頁面很長我需要在指定的地方分頁那怎麼辦呢? wkhtmltopdf 開發者在開發的時候並不是沒有考慮到這一點,
wkhtmltopdf 有個很好的方法,就是在那個div的樣式後新增一個:page-break-inside:avoid;就ok了。
例如

div{ width:800px; min-height:1362px;margin:auto;page-break-inside:avoid;}

以上就是個人總結的轉pdf的方法,很多地方還可以擴充套件,小夥伴們開動腦筋動起來吧,不過目前一直沒有解決就是沒法用中文名稱命名檔案,如果有能解決的夥伴,麻煩在下面留言告知,謝謝麼麼噠了!