-
-
Notifications
You must be signed in to change notification settings - Fork 246
Expand file tree
/
Copy pathE005_header_footer.php
More file actions
293 lines (233 loc) · 9.6 KB
/
E005_header_footer.php
File metadata and controls
293 lines (233 loc) · 9.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<?php
/**
* E005_header_footer.php
*
* @since 2026-04-19
* @category Library
* @package Pdf
* @author Nicola Asuni <info@tecnick.com>
* @copyright 2002-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
* @link https://github.com/tecnickcom/tc-lib-pdf
*
* This file is part of tc-lib-pdf software library.
*/
// NOTE: run make deps fonts in the project root to generate the dependencies and example fonts.
// autoloader when using Composer
require(__DIR__ . '/../vendor/autoload.php');
// define fonts directory
\define('K_PATH_FONTS', \realpath(__DIR__ . '/../vendor/tecnickcom/tc-lib-pdf-font/target/fonts'));
// autoloader when using RPM or DEB package installation
//require ('/usr/share/php/Com/Tecnick/Pdf/autoload.php');
// ----------
/**
* Custom PDF class with a repeating page header and footer.
*
* Extends Tcpdf and overrides defaultPageContent() so that every
* new page automatically receives a branded header and a numbered footer.
* The mechanism is activated by calling enableDefaultPageContent(true).
*/
class PdfWithHeaderFooter extends \Com\Tecnick\Pdf\Tcpdf
{
/** Horizontal margin used by the header and footer bands (mm). */
private const HF_MARGIN = 10.0;
/** Height of the header band (mm). */
private const HEADER_H = 12.0;
/** Height of the footer band (mm). */
private const FOOTER_H = 10.0;
/** Document title shown left-aligned in the header. */
private string $headerTitle = '';
/** Subtitle / date shown right-aligned in the header. */
private string $headerSubtitle = '';
/**
* Set the text displayed in the page header.
*
* @param string $title Left-aligned title.
* @param string $subtitle Right-aligned subtitle (e.g. date or company name).
*/
public function setHeaderText(string $title, string $subtitle): void
{
$this->headerTitle = $title;
$this->headerSubtitle = $subtitle;
}
/**
* Generates the repeating header and footer for every page.
*
* This method is called automatically by setPageContext() whenever a new
* page is added, provided enableDefaultPageContent(true) has been called.
*
* @param int $pid Page index (0-based).
*
* @return string Raw PDF stream prepended to the page content.
*/
public function defaultPageContent(int $pid = -1): string
{
if ($pid < 0) {
$pid = $this->page->getPageId();
}
// Insert the default font once and cache it for subsequent pages.
if ($this->defaultfont === null) {
$this->defaultfont = $this->font->insert($this->pon, 'helvetica', '', 9);
}
$page = $this->page->getPage($pid);
$pw = $page['width'];
$ph = $page['height'];
$lm = self::HF_MARGIN; // left margin x
$rm = $pw - self::HF_MARGIN; // right margin x
$tw = $pw - (2 * self::HF_MARGIN); // usable band width
$lineStyle = [
'lineWidth' => 0.25,
'lineCap' => 'butt',
'lineJoin' => 'miter',
'dashArray' => [],
'dashPhase' => 0,
'lineColor' => '#555555',
];
$out = '';
// ---- HEADER ------------------------------------------------
$headerY = self::HF_MARGIN;
$headerOut = $this->graph->getStartTransform();
$headerOut .= $this->defaultfont['out'];
// Title – left-aligned, bold
if ($this->headerTitle !== '') {
$bfontBold = $this->font->insert($this->pon, 'helvetica', 'B', 10);
$headerOut .= $bfontBold['out'];
$headerOut .= $this->color->getPdfColor('#1a3a6b');
$headerOut .= $this->getTextCell(
$this->headerTitle,
$lm,
$headerY,
$tw * 0.65, // 65 % of the usable width
self::HEADER_H,
0,
0,
'C', // valign: centre inside the band
'L', // halign: left
);
$headerOut .= $this->defaultfont['out'];
}
// Subtitle – right-aligned
if ($this->headerSubtitle !== '') {
$headerOut .= $this->color->getPdfColor('#555555');
$headerOut .= $this->getTextCell(
$this->headerSubtitle,
$lm + $tw * 0.65,
$headerY,
$tw * 0.35, // remaining 35 %
self::HEADER_H,
0,
0,
'C', // valign: centre inside the band
'R', // halign: right
);
}
// Separator line below the header
$headerLineY = $headerY + self::HEADER_H;
$headerOut .= $this->graph->getLine($lm, $headerLineY, $rm, $headerLineY, $lineStyle);
$headerOut .= $this->graph->getStopTransform();
$out .= $this->beginArtifact('Pagination', 'Header');
$out .= $headerOut;
$out .= $this->endArtifact();
// ---- FOOTER ------------------------------------------------
$footerLineY = $ph - self::HF_MARGIN - self::FOOTER_H;
$footerOut = $this->graph->getStartTransform();
$footerOut .= $this->defaultfont['out'];
// Separator line above the footer
$footerOut .= $this->graph->getLine($lm, $footerLineY, $rm, $footerLineY, $lineStyle);
// Page number – centred
$footerOut .= $this->color->getPdfColor('#555555');
$footerOut .= $this->getTextCell(
'Page ' . ($pid + 1),
$lm,
$footerLineY,
$tw,
self::FOOTER_H,
0,
0,
'C', // valign: centre inside the band
'C', // halign: centre
);
$footerOut .= $this->graph->getStopTransform();
$out .= $this->beginArtifact('Pagination', 'Footer');
$out .= $footerOut;
$out .= $this->endArtifact();
return $out;
}
}
// ----------
// main PDF object using the custom subclass
$pdf = new PdfWithHeaderFooter(
'mm', // string $unit = 'mm',
true, // bool $isunicode = true,
false, // bool $subsetfont = false,
true, // bool $compress = true,
'pdfua1', // string $mode = 'pdfua1',
null, // ?ObjEncrypt $objEncrypt = null,
);
// ----------
$pdf->setCreator('tc-lib-pdf');
$pdf->setAuthor('Nicola Asuni');
$pdf->setSubject('tc-lib-pdf example: 005');
$pdf->setTitle('Header & Footer Example');
$pdf->setKeywords('TCPDF tc-lib-pdf example header footer');
$pdf->setPDFFilename('005_header_footer.pdf');
$pdf->setViewerPreferences(['DisplayDocTitle' => true]);
$pdf->setLanguageArray(['a_meta_language' => 'en-US']);
// Set the text that will appear in the header on every page.
$pdf->setHeaderText('My Document Title', \date('Y-m-d'));
// Enable automatic header/footer: calls defaultPageContent() for every new page.
$pdf->enableDefaultPageContent();
// ----------
// Insert fonts
$bfont = $pdf->font->insert($pdf->pon, 'helvetica', '', 11);
$bfontB = $pdf->font->insert($pdf->pon, 'helvetica', 'B', 13);
// ----------
// Add first page
$page01 = $pdf->addPage();
$pdf->setBookmark('Page 1', '', 0, -1, 0, 0, 'B', 'blue');
// Page content starts below the header band (HF_MARGIN + HEADER_H + separator ≈ 25 mm).
$contentY = 28.0;
$pdf->page->addContent($bfontB['out']);
$title1 = $pdf->getTextCell(
'Page 1 — Custom Repeating Header & Footer',
10, $contentY, 190, 0, 0, 0, 'T', 'L',
);
$pdf->page->addContent($title1);
$pdf->page->addContent($bfont['out']);
$body1 = 'This is the first page of a document that demonstrates how to add a custom page header and footer that automatically repeats on every new page using tc-lib-pdf.
The header displays the document title (left) and the date (right), separated from the page content by a thin horizontal rule. The footer shows the page number centred at the bottom, also separated by a horizontal rule.
This is achieved by subclassing \Com\Tecnick\Pdf\Tcpdf and overriding the public defaultPageContent() method, then activating the mechanism once with enableDefaultPageContent(true) before adding any pages.
Because setPageContext() calls defaultPageContent() automatically every time addPage() is used, the header and footer appear on every page without any additional code in the page-building section.';
$txt1 = $pdf->getTextCell(
$body1,
10, $contentY + 10, 190, 0,
15, // first-line indent (mm)
2, // extra line spacing (mm)
'T', 'J',
);
$pdf->page->addContent($txt1);
// ----------
// Add second page
$page02 = $pdf->addPage();
$pdf->setBookmark('Page 2', '', 0, -1, 0, 0, 'B', 'green');
$pdf->page->addContent($bfontB['out']);
$title2 = $pdf->getTextCell(
'Page 2 — Continued Content',
10, $contentY, 190, 0, 0, 0, 'T', 'L',
);
$pdf->page->addContent($title2);
$pdf->page->addContent($bfont['out']);
$body2 = 'This is the second page. The header and footer are present here too without any manual intervention — the overridden defaultPageContent() method takes care of them automatically.
Any further pages added with addPage() would also receive the same header and footer, making the approach suitable for multi-page reports, invoices, or any document type that requires consistent page decoration.';
$txt2 = $pdf->getTextCell(
$body2,
10, $contentY + 10, 190, 0,
15, // first-line indent (mm)
2, // extra line spacing (mm)
'T', 'J',
);
$pdf->page->addContent($txt2);
// ----------
// Output the PDF
$rawpdf = $pdf->getOutPDFString();
$pdf->renderPDF($rawpdf);