参考:史上最强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:\htmlToPDFApp\pdf\header.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 CanGelis\PDF; use League\Flysystem\AdapterInterface;
use \League\Flysystem\Filesystem;
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 CanGelis\PDF\PDF($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{ width: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{ width: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 Files\wkhtmltopdf\bin>wkhtmltopdf.exe --footer-right [page]/[topage] --javascript-delay -T -R -L -B
--enable-javascript --enable-plugins "http://blog.sunansheng.com/python/odoo/odoo.html" oddo.pdf
完毕。