PHP -------wkhtmltopdf的使用方法

一.問題描述php

須要用php把html生成pdf,找了了個php擴展,HTML2PDF,只能生成一些簡單的HTML代碼,複雜的HTML+css沒法生成。網上找到了強大的wkhtmltopdf。css

二.wkhtmltopdf介紹html

工具全名叫 "wkhtmltopdf" ; 是一個使用 Qt WebKit 引擎作渲染的,可以把html 文檔轉換成 pdf 文檔 或 圖片(image) 的命令行工具。(強調一下:是 「命令行工具」 )支持多個平臺,可在win,linux,os x 等系統下運行。linux

三.wkhtmltopdf安裝(linux環境)shell

安裝步驟很簡單,我在這裏就不贅述了,具體能夠參照(https://blog.csdn.net/assasin...://blog.csdn.net/qq_26562641/article/details/72875344),裏面寫的都很詳細瀏覽器

問題1:測試後發現,生成的pdf文件對中文並不支持(外國人寫的軟件,這個沒辦法)?

答案:自行下載中文字體,安裝在linux的字體庫,具體方法能夠參照(https://yq.aliyun.com/ziliao/269854)進行操做,其中字體能夠在此網站下載(http://www.font5.com.cn/font_download.php?id=150&part=1237886897)


                             ***下面是重點戲!!!!!!!***

三.php操做wkhtmltopdf緩存

方法:1.一個是exec執行

     2.擴展包操做(建議採用,本文介紹的就是這個方法,因爲咱們是採用php語言開發,因此我在composer中選用了 
     
         mikehaertl/phpwkhtmltopdf包)

四.mikehaertl/phpwkhtmltopdf包的具體使用服務器

1.包的安裝(composer很方便)composer

2.具體使用能夠參照該包的使用說明socket

3.使用中出現的問題:

q.在本地環境測試能夠正常的下載,可是在linux環境下卻不行?
    a.php.ini的禁用函數 proc_open()要去除,若是不行(將禁用函數去除)
    
    q.php.ini中的禁用函數去除後,仍是不行,槽糕的是,把服務器搞的沒法訪問(解決辦法:清除瀏覽器緩存)?
    a.說的這個問題,咱們來科普一下proc_open()---php內置函數
    
        proc_open():執行一個命令,而且打開用來輸入/輸出的文件指針。
        
        
        wkhtmltopdf使用該命令,來進行pdf文件的生成&寫入工做(生成&寫入基於管道命令),因此在輸入&輸出有一方出現問題,就會致使,該管道沒法關閉,從而出現管道阻塞,從而致使宕機。見代碼(取自:vendor/mikehaertl/php-shellcommand/Command.php文件總的execute方法片斷):
        
        $process = proc_open($command, $descriptors, $pipes, $this->procCwd, $this->procEnv, $this->procOptions);
        if (is_resource($process)) {
            if ($this->_stdIn!==null) {
                if (is_resource($this->_stdIn) &&
                    in_array(get_resource_type($this->_stdIn), array('file', 'stream'), true)) {
                    stream_copy_to_stream($this->_stdIn, $pipes[0]);
                } else {
                    fwrite($pipes[0], $this->_stdIn);
                }
                fclose($pipes[0]);
            }
            $this->_stdOut = stream_get_contents($pipes[1]);
            $this->_stdErr = stream_get_contents($pipes[2]);
            fclose($pipes[1]);
            fclose($pipes[2]);

            $this->_exitCode = proc_close($process);

            if ($this->_exitCode!==0) {
                $this->_error = $this->_stdErr ? $this->_stdErr : "Failed without error message: $command";
                return false;
            }
        } else {
            $this->_error = "Could not run command $command";
            return false;
        }
        
        
        代碼中的$descriptors,規定了包含了要傳送至進程的管道的描述信息。 第一個元素爲描述符類型, 第二個元素是針對該描述符的選項。 有效的類型有:pipe (第二個元素能夠是: r 向進程傳送該管道的讀取端,w 向進程傳送該管道的寫入端), 以及 file(第二個元素爲文件名)。

表達一個真實文件描述符的流資源類型 (例如:已打開的文件,一個 socket 端口,STDIN)。

而我在實際調試中卻發現,我在本地調試時,該參數寫入端爲w,而linux中寫入端爲r,這個是宕機的罪魁禍首。進行代碼分析:
     $descriptors = array(
            1   => array('pipe','w'),
            2   => array('pipe', $this->getIsWindows() ? 'a' : 'w'),

        );
     public function getIsWindows()
     {
    return strncasecmp(PHP_OS, 'WIN', 3)===0;
    }
    
    將 2   => array('pipe', $this->getIsWindows() ? 'a' : 'w'),=》修改成  2   => array('pipe', 'a'),問題解決。
相關文章
相關標籤/搜索