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
完毕。