如何解决使用CakePdf显示页眉和页脚
我正在尝试使用CakePdf 3.5.3和wkhtmltopdf engine来呈现pdf,并且每页上的html标头都显示自定义文本以及页码。
https://wkhtmltopdf.org/usage/wkhtmltopdf.txt将过程描述为传递--header-html
命令行参数并使用以下javascript和html:
<!DOCTYPE html>
<html><head><script>
function subst() {
var vars = {};
var query_strings_from_url = document.location.search.substring(1).split('&');
for (var query_string in query_strings_from_url) {
if (query_strings_from_url.hasOwnProperty(query_string)) {
var temp_var = query_strings_from_url[query_string].split('=',2);
vars[temp_var[0]] = decodeURI(temp_var[1]);
}
}
var css_selector_classes = ['page','frompage','topage','webpage','section','subsection','date','isodate','time','title','doctitle','sitepage','sitepages'];
for (var css_class in css_selector_classes) {
if (css_selector_classes.hasOwnProperty(css_class)) {
var element = document.getElementsByClassName(css_selector_classes[css_class]);
for (var j = 0; j < element.length; ++j) {
element[j].textContent = vars[css_selector_classes[css_class]];
}
}
}
}
</script></head><body style="border:0; margin: 0;" onload="subst()">
<table style="border-bottom: 1px solid black; width: 100%">
<tr>
<td class="section"></td>
<td style="text-align:right">
Page <span class="page"></span> of <span class="topage"></span>
</td>
</tr>
</table>
</body></html>
我创建了src/Template/Layout/pdf/default.ctp
和src/Template/Layout/pdf/header.ctp
default.ctp
<!DOCTYPE html>
<html lang="en">
<head>
<?= $this->Html->charset() ?>
<title>
<?= $this->fetch('title') ?>
</title>
<?= $this->Html->meta('icon') ?>
</head>
<body>
<?= $this->Flash->render() ?>
<div>
<?= $this->fetch('content') ?>
</div>
</body>
</html>
header.ctp
<!DOCTYPE html>
<html lang="en">
<head>
<script>
function subst() {
var vars = {};
var query_strings_from_url = document.location.search.substring(1).split('&');
for (var query_string in query_strings_from_url) {
if (query_strings_from_url.hasOwnProperty(query_string)) {
var temp_var = query_strings_from_url[query_string].split('=',2);
vars[temp_var[0]] = decodeURI(temp_var[1]);
}
}
var css_selector_classes = ['page','sitepages'];
for (var css_class in css_selector_classes) {
if (css_selector_classes.hasOwnProperty(css_class)) {
var element = document.getElementsByClassName(css_selector_classes[css_class]);
for (var j = 0; j < element.length; ++j) {
element[j].textContent = vars[css_selector_classes[css_class]];
}
}
}
}
</script>
<title></title>
</head>
<body onload="subst()">
<?= $some_view_variable ?>
Page <span class="page"></span> of <span class="topage"></span>
</body>
</html>
这是我在控制器中配置CakePdf的方式。
Configure::write('CakePdf',[
'engine' => [
'className' => 'CakePdf.WkHtmlToPdf','binary' => "/usr/local/bin/wkhtmltopdf",'options' => [
'header-html' => APP . 'Template' . DS . 'Layout' . DS . 'pdf' . DS . 'header.ctp',],'margin' => [
'bottom' => 0,'left' => 0,'right' => 0,'top' => 0
],'pageSize' => 'Letter','orientation' => 'portrait'
]);
标题信息未显示在生成的PDF中。我也不确定如何将viewVars传递到标题模板。
解决方法
我的理解是,标题必须位于.html
文件中,并且必须为原始HTML(例如,不是Cake模板),并且我还没有找到指定header-html
选项的方法。这是我以前解决过的技巧:
$view = new View();
$dir = TMP . 'html';
if (!is_dir($dir)) {
mkdir($dir);
}
while (true) {
// WkHtmlToPdf requires .html extension on these files,but tempnam can't do that.
$file = tempnam($dir,'header');
if (rename($file,$file . '.html')) {
$file .= '.html';
break;
} else {
unlink($file);
}
}
file_put_contents($file,'<!DOCTYPE HTML><html lang=\'en-US\'><body style=\'font-family: "Times New Roman"\'>' . $view->element($element) . '</body></html>');
// Hack to access protected member: we want --header-html on the command line.
// This is easier than extending the class for a single such usage.
$closure = function($file) {
$this->_header = ['html' => 'file://' . $file];
};
$hack = \Closure::bind($closure,$pdf,'CakePdf\Pdf\CakePdf');
$hack($file);
$this->_tmp[] = $file;
当然,这是在单独的功能中完成的,因此,如果我找到更好的方法,则很容易替换。 :-)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。