【发布时间】:2019-01-15 18:01:51
【问题描述】:
我已经为此苦苦挣扎了一段时间,感到无助。 Prestashop 使用tcpdf 从使用 Smarty 填充的 HTML 模板生成发票和交货单。我们正在努力更新发票设计,发现 tcpdf 缺乏 CSS 支持。经过一些研究,我们选择了wkhtmltopdf 作为将 HTML/CSS 模板转换为 PDF 的正确工具。
问题
商店具有将多张发票导出为单个 PDF 的功能。使用TCPDF,我能够通过在每张发票之后插入一个空白页来使批处理文件准备好进行双面打印,该发票在文件生成之前具有奇数页。但是现在我们切换到wkhtmltopdf 我无法获得相同的结果。
关键的问题是虽然wkhtmltopdf 允许使用多个HTML 模板,但似乎没有可靠的方法来determine the number of pages 在文件生成之前它们每个都将拥有。页眉和页脚模板可以接收发票最终的页数,但它们与主要内容是分开的,因此我无法相应地插入分页符。
我也尝试计算height of the content / PDF page height,但是一旦我开始导出多个模板(使用单个模板工作正常),就有various issues。这种方法也不是很好,因为将空白页面插入内容本身会导致页脚也出现在新页面上,这不是我想要的。
我的最佳尝试
我想出解决这些问题的唯一方法是非常低效的。每次将模板添加到批处理中时,我都可以使用 wkhtmltopdf 的 wrapper 的单独实例预先生成它,获取临时文件名,使用 pdfinfo 确定它有多少页并添加空白 HTML模板相应地添加到主实例。这是一个函数的草稿,用于获取添加的最后一个模板的页数(来自扩展包装器的类,基于我在 SO 上找到的其他一些 pdfinfo questions):
/**
* Return the number of pages in the last invoice template added
* $complete === true => return the length of the entire document
*/
public function getNumPages($complete = false)
{
if (!$complete) {
// Generate PDF of last template added
$tmpPdf = new WKPdf($this->_options);
$tmpPdf->addPage($this->content, Array(
'footer-html' => $this->footer
));
/**
The createPdf method is protected so I need to get
the content as string here to force the wrapper to
call wkhtmltopdf.
*/
$tmpPdf->toString();
$document = $tmpPdf->getPdfFilename();
} else {
// Generate entire batch
$this->createPdf();
$document = $this->getPdfFilename();
}
// Use pdfinfo to get the PDF page count
$cmd = 'pdfinfo';
exec("$cmd \"$document\"", $output);
$pagecount = 0;
foreach($output as $op)
{
// Extract the number
if(preg_match("/Pages:\s*(\d+)/i", $op, $matches) === 1)
{
$pagecount = intval($matches[1]);
break;
}
}
return $pagecount;
}
这非常低效 - 生成一批 25 张发票大约需要 80 秒,因为我必须调用 wkhtmltopdf 25 次来创建临时 PDF 文件,以便我可以调用 pdfinfo 25 次以获取他们的个人长度并在必要时插入空白页,然后生成最终文档。
TCPDF 的优势在于它可以为您提供动态的页数,并且类似的功能需要大约 5 秒来生成包含 25 张发票的批处理文件。
有人对如何加快速度有任何想法吗?或者一个更好的主意完全这样做。我考虑过包括 dompdf 在内的各种生成工具,但 wkhtmltopdf 是最强大的。批量生成实际上仅由商店管理员在后台使用,因此也许他们可以耐心等待。但还是。
【问题讨论】:
-
我已经尝试用 Fpdi 库替换
pdfinfo。不太喜欢使用两个工具(实际上是三个因为 Fpdi 需要 Fpdf...)来实现如此简单的事情。 -
有趣。我会在周末看看这个。我相信我可能有一个会有所帮助的解决方案,但有一些“如果”。我相信我能以某种方式提供帮助。周末后再回来看看。
-
我可能会使用 TCPDF 并使用背景图像方法,然后将自定义文本放在您想要的位置。如果您真的想避免使用 TCPDF(看看他们的文档,我就明白了),那么也许您可以通过为每个 PDF 制作线程来帮助您节省时间 stackoverflow.com/questions/70855/…
-
@PeterTheLobster,请给我一些应该生成的示例 PDF 文件(互联网链接)。如果我理解正确,那么在每张 A4 格式的发票之后是一个空白页吗?
-
@Bharata 嘿,对不起。我认为我目前无法为您提供示例文件,因为我没有与客户协商过。我们基本上是在尝试生成包含多张发票的单个 PDF。由于订购的物品数量或客户数据的数量,每张发票的长度可能在 1 到 3 页之间。因此,在生成包含多张发票的批量 pdf 时,我需要在每张奇数页(1、3 等)的发票之后插入一个空白页,以便可以双面打印整个文件(以避免在同一张纸)。
标签: php pdf wkhtmltopdf prestashop-1.5