3

TL;DR: PHP 生成总页数超过 1 页的 PDF 时遇到问题。


再一次问好。我的目标是创建一个脚本,它基本上可以获取所有重要数据,并创建一个 A4 格式的 PDF 发票/文档,用于打印/邮寄/存档。只要文档不溢出,生成 PDF 文档就可以了。

我希望发票页面带有边框,它应该包含:

  • 发票有效所需的材料
  • 计费产品/其他信息
  • 供应商/客户签名和盖章或其他数据的地方

所有页面都必须包含页眉和页脚(公司徽标)和页脚(第 # 页,共 # 页 - 发票/文档 ID - 日期和时间 - 办公室 ID - 打印机 ID、指定人员、任何人可以询问的内容),以及周围的边框文档正文(页眉下方,页脚上方)。

只要文档大小不大于

$pageSize-$pageMargins-$header-$footer-$invoiceDataBlock-$signaturesBlock

这基本上就像实际发票项目的 10 厘米。如果文档更大,我实际上是使用电子表格编辑器手动为发票创建附件。

问题是:我可以做些什么来创建一个没有问题的多页 PDF 文档,例如覆盖页眉/页脚的发票项目?我需要知道何时继续下一页。我怎么知道这个?完成这项任务的最佳方法是什么?

先感谢您!

4

2 回答 2

2

我已经使用 FPDF 和 TCPDF 来生成多页发票文件。它们的工作方式大致相同。(我从 FPDF 开始,然后在需要包含 Unicode 字符时切换到 TCPDF,当时 FPDF 不支持。)

正如 Eugen 所建议的,与使用 FPDF 或 TCPPDF 中内置的函数相比,您可以更轻松地手动滚动自己的页眉和页脚。

我确保不覆盖页脚的策略只是小心发票中包含的数据。添加新 SKU 时,我会测试长名称以确保它们适合发票 PDF 中的字段。对于必须是可变长度的项目,我将未知内容放在自己的行中以减少可能的影响:

域名注册(2 年)
example.com

当我生成发票的每一页时,我会跟踪我使用了多少行。我知道我可以安全地放 20 行项目,并且我知道我的最大单个项目是 2 行,然后当我达到 20 行时,我开始一个新的页面。15 项表示 1 页。25 项意味着两页。项目计数器上升,每次我达到 20 行限制时,它都会生成下一页并重置页面项目计数器。

请注意,我没有在此答案中包含任何代码,因为您的问题中没有包含任何代码。如果您需要实施方面的帮助,我怀疑这将成为另一个问题的理由。:-)

于 2012-06-03T02:49:53.090 回答
1

Use TCPDF. It has a very handy SetY() / GetY() pair of functions, that allows you to know, where on the page you are. You can use this to know when to do a page break.

Hint: Do not use the Header/Footer capabilities - they are clunky. Draw your own headers/footers.

Edit

As from discussion below, here are some details: To avoid overlaying you have 2 possibilities

  1. Use getStringHeight() and calculate
  2. Use Transactions

The first version draws its rationale from the fact, that of all objects you typically use in generating a PDF a text-flow is the only one, of which you cannot tell beforehand the height it will use. getStringHeight() provides you with a good enough estimate, so you know before adding the element, if it will fit on the page (leaving enough room on the bottom for the footer). So basically you extend your drawing loop to calculate the height of each element and test, if you need to start a new page first. This allows also for some sort of keeptogether, e.g. if the remaining space after a section title is too low, start a new page before, to keep section title and section body together.

The second version is even easier: In TCPDF you can use transactions simialr to a Database: Start a transaction, draw, if the result is not to your liking roll back, else commit. We found this to be quite a performance hog, ultimately deciding against it for long textual reports, but a 2-page invoice is a very different beast.

于 2012-06-02T23:27:31.573 回答