zoukankan      html  css  js  c++  java
  • php使用wkhtmltopdf导出pdf

    参考:史上最强php生成pdf文件,html转pdf文件方法

           http://biostall.com/wkhtmltopdf-add-header-footer-to-only-first-last-page/ 指定页面显示或者因此header和footer

            http://blog.csdn.net/sibang/article/details/38733305

    wkhtmltopdf "www.baidu.com" --header-html "D:htmlToPDFApppdfheader.html" baidu.pdf
    wkhtmltopdf --javascript-delay 3000 -T 0 -R 0 -L 0 -B 0 --enable-javascript --enable-plugins http://didc.iwom-trends.com/bhqkgk.aspx 88-10TEST.PDF

    下载地址http://code.google.com/p/wkhtmltopdf/downloads/detail?name=wkhtmltox-0.11.0_rc1-installer.exe&can=2& --JavaScript-delay 3000 可以延迟加载(主要作用是解决页面加载不完整的现象)

    延时加载js,--JavaScript-delay 3000  解决js加载不完全如下类:

    <?php namespace CanGelisPDF;
    
    use LeagueFlysystemAdapterInterface;
    use LeagueFlysystemFilesystem;
    class PDF {
    
        /**
         * Random name that will be the name of the temporary files
         *
         * @var string
         */
        protected $fileName;
    
        /**
         * Folder in which temporary files will be saved
         *
         * @var string
         */
        protected $folder;
    
        /**
         * HTML content that will be converted to PDF
         *
         * @var string
         */
        protected $htmlContent = null;
    
        /**
         * Params to be executed by wkhtmltopdf
         *
         * @var array
         */
        protected $params = array();
    
        /**
         * Input Path that will be generated to PDF Doc.
         *
         * @var string
         */
        protected $path = null;
    
        /**
         * PDF File's Binary content
         *
         * @var mixed
         */
    
        protected $contents = null;
    
        /**
         * Available command parameters for wkhtmltopdf
         *
         * @var array
         */
        protected $availableParams = array(
            'grayscale', 'orientation', 'page-size',
            'lowquality', 'dpi', 'image-dpi', 'image-quality',
            'margin-bottom', 'margin-left', 'margin-right', 'margin-top',
            'page-height', 'page-width', 'no-background', 'encoding', 'enable-forms',
            'no-images', 'disable-internal-links', 'disable-javascript',
            'password', 'username', 'footer-center', 'footer-font-name',
            'footer-font-size', 'footer-html', 'footer-left', 'footer-line',
            'footer-right', 'footer-spacing', 'header-center', 'header-font-name',
            'header-font-size', 'header-html', 'header-left', 'header-line', 'header-right',
            'header-spacing', 'print-media-type', 'zoom','javascript-delay'
        );
    
        /**
         * wkhtmltopdf executable path
         *
         * @var string
         */
        protected $cmd;
    
        /**
         * Initialize temporary file names and folders
         */
        public function __construct($cmd, $tmpFolder = null)
        {
            $this->cmd = $cmd;
            $this->addParam('javascript-delay',5000);//增加延时执行js,add by zhaoliang 20170215
            $this->fileName = uniqid(rand(0, 99999));
    
            if (is_null($tmpFolder))
            {
                $this->folder = sys_get_temp_dir();
            } else
            {
                $this->folder = $tmpFolder;
            }
    
    
        }
    
        /**
         * Loads the HTML Content from plain text
         *
         * @param string $html
         *
         * @return $this
         */
        public function loadHTML($html)
        {
            $this->htmlContent = $html;
    
            return $this;
        }
    
        /**
         * Loads the input source as a URL
         *
         * @param string $url
         *
         * @return $this
         */
        public function loadUrl($url)
        {
            return $this->setPath($url);
        }
    
        /**
         * Loads the input source as an HTML File
         *
         * @param $file
         *
         * @return $this
         */
        public function loadHTMLFile($file)
        {
            return $this->setPath($file);
        }
    
        /**
         * Generates the PDF and save the PDF content for the further use
         *
         * @return string
         * @throws PDFException
         */
        public function generate()
        {
            $returnVar = $this->executeCommand($output);
    
            if ($returnVar == 0)
            {
                $this->contents = $this->getPDFContents();
            } else
            {
                throw new PDFException($output);
            }
    
            $this->removeTmpFiles();
    
            return $this;
        }
    
    
        /**
         * Saves the pdf content to the specified location
         *
         * @param $fileName
         * @param AdapterInterface $adapter
         * @param bool $overwrite
         *
         * @return $this
         */
        public function save($fileName, AdapterInterface $adapter, $overwrite = false)
        {
            $fs = new Filesystem($adapter);
    
            if ($overwrite == true) {
                $fs->put($fileName, $this->get());
            } else {
                $fs->write($fileName, $this->get());
            }
    
            return $this;
        }
    
        public function get()
        {
            if (is_null($this->contents)) {
                $this->generate();
            }
            return $this->contents;
        }
    
        /**
         * Remove temporary HTML and PDF files
         */
        public function removeTmpFiles()
        {
            if (file_exists($this->getHTMLPath()))
            {
                @unlink($this->getHTMLPath());
            }
            if (file_exists($this->getPDFPath()))
            {
                @unlink($this->getPDFPath());
            }
        }
    
        /**
         * Gets the contents of the generated PDF
         *
         * @return string
         */
        public function getPDFContents()
        {
            return file_get_contents($this->getPDFPath());
        }
    
        /**
         * Execute wkhtmltopdf command
         *
         * @param array &$output
         *
         * @return integer
         */
        public function executeCommand(&$output)
        {
            $descriptorspec = array(
                0 => array("pipe", "r"), // stdin is a pipe that the child will read from
                1 => array("pipe", "w"), // stdout is a pipe that the child will write to
                2 => array("pipe", "w") // stderr is a pipe that the child will write to
            );
    
            $process = proc_open($this->cmd . ' ' . $this->getParams() . ' ' . $this->getInputSource() . ' ' . $this->getPDFPath(), $descriptorspec, $pipes);
    
            $output = stream_get_contents($pipes[1]) . stream_get_contents($pipes[2]);
    
            fclose($pipes[0]);
            fclose($pipes[1]);
            fclose($pipes[2]);
    
            return proc_close($process);
        }
    
    
        /**
         * Gets the parameters defined by user
         *
         * @return string
         */
        protected function getParams()
        {
            $result = "";
            foreach ($this->params as $key => $value)
            {
                if (is_numeric($key))
                {
                    $result .= '--' . $value;
                } else
                {
                    $result .= '--' . $key . ' ' . '"' . $value . '"';
                }
                $result .= ' ';
            }
            return $result;
        }
    
        /**
         * Sets the input argument for wkhtmltopdf
         *
         * @param $path
         *
         * @return $this
         */
        protected function setPath($path)
        {
            $this->path = $path;
    
            return $this;
        }
    
        /**
         * Adds a wkhtmltopdf parameter
         *
         * @param string $key
         * @param string $value
         */
        protected function addParam($key, $value = null)
        {
            if (is_null($value))
            {
                $this->params[] = $key;
            } else
            {
                $this->params[$key] = $value;
            }
    
        }
    
        /**
         * Converts a method name to a wkhtmltopdf parameter name
         *
         * @param string $method
         *
         * @return string
         */
        protected function methodToParam($method)
        {
            return snake_case($method, "-");
        }
    
        /**
         * Gets the Input source which can be an HTML file or a File path
         *
         * @return string
         */
        protected function getInputSource()
        {
            if (!is_null($this->path))
            {
                return $this->path;
            }
    
            file_put_contents($this->getHTMLPath(), $this->htmlContent);
    
            return $this->getHTMLPath();
        }
    
        /**
         * Gets the temporary saved PDF file path
         *
         * @return string
         */
        protected function getPDFPath()
        {
            return $this->folder . '/' . $this->fileName . '.pdf';
        }
    
        /**
         * Gets the temporary save HTML file path
         *
         * @return string
         */
        protected function getHTMLPath()
        {
            return $this->folder . '/' . $this->fileName . '.html';
        }
    
        /**
         * Gets the error file's path in which stderr will be written
         */
        protected function getTmpErrFilePath()
        {
            return $this->folder . '/' . $this->fileName . '.log';
        }
    
        /**
         * Handle method<->parameter conventions
         *
         * @param string $method
         * @param string $args
         *
         * @return $this
         * @throws PDFException
         */
        public function __call($method, $args)
        {
            $param = $this->methodToParam($method);
            if (in_array($param, $this->availableParams))
            {
                if (isset($args[0]))
                {
                    $this->addParam($param, $args[0]);
                } else
                {
                    $this->addParam($param);
                }
                return $this;
            } else
            {
                throw new PDFException('Undefined method: ' . $method);
            }
        }
    
    }

    __construct里面增加了代码$this->addParam('javascript-delay',5000);

    下面是调用函数的部分:

        function generatePdfAction()
        {
            $html =$this->getView()->render('stat/analysis_h_test.php');//analysis_v.php横板
            header('Content-Type: application/pdf');
            header("Content-Disposition:attachment;filename=小文斌的数据分析.pdf");
            $path  = $this->getConfig()->wkhtmltopdf->path;
            $pdf = new CanGelisPDFPDF($path);
            echo $pdf->loadHTML($html)->get();
    
            return false;
        }

     函数名称不能带中划线,不然的话,根本不需要修改__construct,  直接在这里添加$pdf->javascript-delay(2000);语句即可。

    完毕。

    2017年2月16日,如果打印横板的话,参数为--orientation Landscape

    2017年4月29日,解决分页问题:

    解决分页问题
    wkhtmltopdf 很好用,但也有些不尽人意。就是当一个html页面很长我需要在指定的地方分页那怎么办呢? wkhtmltopdf 开发者在开发的时候并不是没有考虑到这一点,
    例如下面这个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>
    <title>pdf</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <style type="text/css">
    *{ margin:0px; padding:0px;}
    div{ 800px; height:1362px;margin:auto;}
    </style>
    <body>
    <div style=" background:#030"></div>
    <div style=" background:#033"></div>
    <div style=" background:#369"></div>
    <div style=" background:#F60"></div>
    <div style=" background:#F3C"></div>
    <div style=" background:#F0F"></div>
    <div style=" background:#0FF"></div>
    <div style=" background:#FF0"></div>
    <div style=" background:#00F"></div>
    <div style=" background:#0F0"></div>
    <div style=" background:#033"></div>
    <div style=" background:#369"></div>
    <div style=" background:#F60"></div>
    <div style=" background:#030"></div>
    <div style=" background:#033"></div>
    <div style=" background:#369"></div>
    <div style=" background:#F60"></div>
    <div style=" background:#F3C"></div>
    <div style=" background:#F0F"></div>
    <div style=" background:#0FF"></div>
    <div style=" background:#FF0"></div>
    <div style=" background:#00F"></div>
    <div style=" background:#0F0"></div>
    </body>
    </html>

    当我把它生成pdf的时候我想让每个块都是一页,经过无数次调试pdf的一页大约是1362px,但是越往后值就不对了,目前还不知道pdf一页是多少像素。

    但是wkhtmltopdf 有个很好的方法,就是在那个div的样式后添加一个:page-break-inside:avoid;就ok了。真正管用的是page-break-before:always;

        <!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>  
        <title>pdf</title>  
        <link href="css/style.css" rel="stylesheet" type="text/css" />  
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
        </head>  
        <style type="text/css">  
        *{ margin:0px; padding:0px;}  
        div{ 800px; min-height:1362px;margin:auto;page-break-inside:avoid;}  
        </style>  
        <body>  
        <div style=" background:#030"></div>  
        <div style=" background:#033"></div>  
        <div style=" background:#369"></div>  
        <div style=" background:#F60"></div>  
        <div style=" background:#F3C"></div>  
        <div style=" background:#F0F"></div>  
        <div style=" background:#0FF"></div>  
        <div style=" background:#FF0"></div>  
        <div style=" background:#00F"></div>  
        <div style=" background:#0F0"></div>  
        <div style=" background:#033"></div>  
        <div style=" background:#369"></div>  
        <div style=" background:#F60"></div>  
        <div style=" background:#030"></div>  
        <div style=" background:#033"></div>  
        <div style=" background:#369"></div>  
        <div style=" background:#F60"></div>  
        <div style=" background:#F3C"></div>  
        <div style=" background:#F0F"></div>  
        <div style=" background:#0FF"></div>  
        <div style=" background:#FF0"></div>  
        <div style=" background:#00F"></div>  
        <div style=" background:#0F0"></div>  
        </body>  
        </html>  

    添加页码:

    wkhtmltopdf专成pdf文件之后的页码显示问题
    在页面header或者footer上面添加page(当前页数)topage(总页数)来显示页码

    wkhtmltopdf 0.12.2.1 (with patched qt) on ubuntu 14 works with <P style="page-break-before: always">
    wkhtmltopdf 0.9.9 used to work with <hr/> to produce a new page.

    https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1551

    wkhtmltopdf --footer-right '[page]/[topage]' http://www.google.com google.pdf
    



    header和footer参数说明

    Headers And Footer Options
    
    --footer-center*	<text>	Centered footer text
    --footer-font-name*	<name>	Set footer font name (default Arial)
    --footer-font-size*	<size>	Set footer font size (default 11)
    --footer-html*	<url>	Adds a html footer
    --footer-left*	<text>	Left aligned footer text
    --footer-line*		Display line above the footer
    --footer-right*	<text>	Right aligned footer text
    --footer-spacing*	<real>	Spacing between footer and content in mm (default 0)
    --header-center*	<text>	Centered header text
    --header-font-name*	<name>	Set header font name (default Arial)
    --header-font-size*	<size>	Set header font size (default 11)
    --header-html*	<url>	Adds a html header
    --header-left*	<text>	Left aligned header text
    --header-line*		Display line below the header
    --header-right*	<text>	Right aligned header text
    --header-spacing*	<real>	Spacing between header and content in mm (default 0)
    


    页码以及时间等参数的说明

     * [page]       Replaced by the number of the pages currently being printed
     * [frompage]   Replaced by the number of the first page to be printed
     * [topage]     Replaced by the number of the last page to be printed
     * [webpage]    Replaced by the URL of the page being printed
     * [section]    Replaced by the name of the current section
     * [subsection] Replaced by the name of the current subsection
     * [date]       Replaced by the current date in system local format
     * [time]       Replaced by the current time in system local format
    

    如下是一条测试语句:

    E:Program Fileswkhtmltopdfin>wkhtmltopdf.exe --footer-right [page]/[topage]  --javascript-delay 3000 -T 0 -R 20 -L 0 -B 10 
    --enable-javascript --enable-plugins "http://blog.sunansheng.com/python/odoo/odoo.html" oddo.pdf

    完毕。

  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    leetcode 213. 打家劫舍 II JAVA
    leetcode 48. 旋转图像 java
    leetcode 45. 跳跃游戏 II JAVA
    leetcode 42. 接雨水 JAVA
    40. 组合总和 II leetcode JAVA
    24. 两两交换链表中的节点 leetcode
    1002. 查找常用字符 leecode
    leetcode 23. 合并K个排序链表 JAVA
  • 原文地址:https://www.cnblogs.com/zl0372/p/wkhtmltopdf.html
Copyright © 2011-2022 走看看