跳转到内容

添加重复显示的页眉与页脚

只需配置一次页眉(一个标题加一段说明)与页脚,layout 引擎就会在每一页绘制它们,包括自动分页生成的页面。请在第一次 addPage() 之前设置好数据。你完全不需要逐页绘制页眉或页脚。本示例遵循 examples/13-header-footer.php

Terminal window
composer require nextpdf/core:^3

不需要任何可选扩展。Layout concern 中的页眉与页脚 API 自 1.0.0 起保持稳定,并且可以在 8.1–8.4 backport 矩阵上运行。

页眉与页脚属于页面装饰元素。layout 引擎会在每一页清出(flush)时,在页面预留的上、下两条区带中绘制它们。setHeaderData() 负责记录内容。setHeaderFont()setHeaderMargin()setFooterFont()setFooterMargin() 用来设置排版字体以及距页面边缘的距离。对于不需要这些装饰元素的文档,可以用 setPrintHeader(false)setPrintFooter(false) 将其关闭。

页眉与页脚的几何位置以页面边界为基准进行测量。页面对象字典(ISO 32000-2 §7.7.3.3)将 MediaBox 项定义为介质边界,并将 CropBox 项定义为页面裁切后的可见区域。14.11.2 节详述了这些页面边界的语义。你设置的页眉边距,就是相对于该边界的偏移量。页眉与页脚的标记不是独立对象;它们是每一页 Contents stream 的一部分,会逐页输出(§7.7.3.3)。

API 接口由 PHPDoc 自动生成。本示例会用到以下方法:

  • setHeaderData(string $title = '', string $description = '', string $logo = '', float $logoWidth = 0): static — 设置页眉内容。
  • setHeaderFont(string $family, float $size = 10): static / setFooterFont(string $family, float $size = 8): static — 页眉与页脚的排版字体。
  • setHeaderMargin(float $margin): static / setFooterMargin(float $margin): static — 距页面边缘的距离,以毫米为单位。
  • setPrintHeader(bool $enabled): static / setPrintFooter(bool $enabled): static — 切换这些装饰元素是否启用。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setHeaderData(title: 'Quarterly Report', description: 'Confidential');
$doc->setHeaderFont('helvetica', 10);
$doc->setFooterFont('helvetica', 8);
$doc->addPage();
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'Body text. The header and footer appear on this page '
. 'and on every page added afterwards, with no per-page code.');
$doc->addPage();
$doc->multiCell(0, 7, 'Page 2 — the furniture repeats automatically.');
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/header-footer.pdf');

这是可直接在测试载具(harness)中运行的完整示例。它会遵循 NEXTPDF_COOKBOOK_OUTPUT,且不会自行固定任何随机种子。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Header and Footer');
// Configure the header once, before the first page. The layout engine
// draws it on every page, including auto-break pages.
$doc->setHeaderData(
title: 'NextPDF Example',
description: 'Header and Footer Demonstration',
);
$doc->setHeaderFont('helvetica', 10);
$doc->setHeaderMargin(5);
// Configure the footer. The footer band carries the page number.
$doc->setFooterFont('helvetica', 8);
$doc->setFooterMargin(10);
$doc->addPage();
$doc->setFont('helvetica', 'B', 16);
$doc->cell(0, 12, 'Document with Header and Footer', newLine: true);
$doc->ln(5);
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'This document has a header with a title and description '
. 'that repeats on every page. The footer shows the page number.');
$doc->addPage();
$doc->setFont('helvetica', '', 11);
$doc->multiCell(0, 7, 'This is page 2. The header and footer appear without '
. 'any additional code on each new page.');
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/header-footer.pdf';
$doc->save($out);
echo "Created header-footer.pdf\n";
  • 请在第一页之前设置好这些装饰元素。 如果在 addPage() 之后才调用 setHeaderData(),先前的页面不会被重绘,因此请在第一次 addPage() 之前完成设置。
  • 页眉边距与正文上边距的区别。 页眉边距表示页眉相对于页面边缘的距离,与正文的上边距彼此独立。如果正文上边距小于页眉区带,两者就可能重叠,因此请预留足够的空间。
  • 装饰元素的关闭是针对整份文档,而非单页。 setPrintHeader(false) 会应用到整份文档。并没有内置的逐页开关。一个不含装饰元素的封面页,应当是另一份独立文档,或是一项刻意的版面设计选择。
  • Logo 路径。 传给 setHeaderData()$logo 参数必须是本地文件路径。图像加载器会拒绝 URL scheme(请参阅图像示例),因此请传入本地文件。

页眉与页脚会逐页绘制。它的成本取决于装饰元素的内容量(少量几段文字),而不是正文大小,因此每页清出(flush)时只会增加可以忽略的额外开销。2000 ms / 64 MB 的预算足以涵盖一份每页都带装饰元素、长达数百页的文档。

页眉的标题与说明会作为文档文字绘制。如果其中包含用户可控的数据,例如租户名称,就必须像处理正文一样限制长度并进行清理。本示例不执行任何解析,也不访问网络。

陈述规范条款参考 ID(reference_id)
MediaBox 这个页面对象字典项定义了页面的介质边界,header/footer 的几何位置以此为基准测量。ISO 32000-2§7.7.3.3
CropBox 这个页面对象字典项是页面裁切后的可见区域。ISO 32000-2§7.7.3.3
页眉与页脚的标记是每一页 Contents stream 的一部分。ISO 32000-2§7.7.3.3

可复现性画像 — 结构层级。 trailer 的 /ID 以及 /CreationDate / /ModDate 原子,会在每次保存时变动。测试载具会剥离这些原子,再比对经 qpdf 规范化后的结构。本示例描述 NextPDF 如何生成这套结构;它并不声称全面符合 ISO 32000-2。

不适用。重复显示的页眉与页脚是 Core 的能力,没有 Premium gate。