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'),问题解决。
相关文章
相关标签/搜索