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

    完毕。

  • 相关阅读:
    springboot小技巧(转)
    spring boot项目如何测试,如何部署
    thymeleaf模板的使用(转)
    springboot+多数据源配置
    springboot+shiro
    springboot+jpa+thymeleaf增删改查的示例(转)
    SpringBoot ( 七 ) :springboot + mybatis 多数据源最简解决方案
    tcpdump查看某个端口数据
    oracle完全删除表空间
    检测python进程是否存活
  • 原文地址:https://www.cnblogs.com/zl0372/p/wkhtmltopdf.html
Copyright © 2011-2022 走看看