HTML als PDF-Seiteninhalt rendern
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Dieses Recipe wandelt ein Fragment aus HTML und CSS mit einer einzigen Methode in PDF-Seiteninhalt um: writeHtml(). Übergeben Sie der Methode Markup; sie rendert daraus eine formatierte Seite. Die vollständige, lauffähige Version dieses Codes finden Sie unter examples/08-html-basic.php. Folgen Sie den Schritten weiter unten, oder kopieren Sie das Beispiel direkt.
NextPDF liest Ihr HTML in einem einzigen Durchlauf und streamt das Ergebnis direkt auf die Seite. Das ist eine Single-Pass-Streaming-Pipeline. Sie müssen dieses Modell nicht verstehen, um das Recipe zu nutzen; Sie sollten es aber im Hinterkopf behalten, denn es prägt einige der Regeln weiter unten auf dieser Seite.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Dieser Befehl installiert das Paket nextpdf/core. Die Beispiele auf dieser Seite laufen unter PHP 8.4; die unterstützte Laufzeitumgebung ist >=8.4 <9.0.
Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“writeHtml() nimmt eine HTML-Zeichenkette entgegen und zeichnet sie ab der aktuellen Cursor-Position auf die aktuelle Seite. Hier sehen Sie Schritt für Schritt, was intern passiert: Zuerst durchsucht die Engine Ihr HTML einmal und zerlegt es in eine Liste von Tokens (HtmlTokenizer). Anschließend durchläuft sie diese Liste von links nach rechts (HtmlParser). Für jedes Element schreibt sie die passenden PDF-Zeichenanweisungen, also Content-Stream-Operatoren, in einen Puffer. Die Engine baut zwischen den Aufrufen niemals einen Baum Ihrer Elemente auf und hält auch keinen im Speicher. Dieses bewusste Design ist das Single-Pass-Streaming-Modell und in ADR-001 festgehalten.
Jedes unterstützte Block-Element wird zu einer Layout-Box, jeder Textlauf zu einem Text-Show-Operator. Stile aus Inline-style-Attributen und aus einem <style>-Block werden über die CSS-Kaskade aufgelöst, also über die Standardregeln, die entscheiden, welcher Stil gewinnt, wenn mehrere zutreffen. Textumbruch, Ausrichtung und Abstände folgen dem CSS-Text-Modell; es legt fest, wie Quelltext zu formatiertem, zeilenumgebrochenem Text wird (W3C CSS Text Level 3).
Wenn Sie keine Schrift auswählen, verwendet der Fließtext eine Standardschrift. Diese Standardschrift ist eine standardmäßige Type-1-Schrift, also eine der 14 Standardschriften, die in ISO 32000-2 benannt sind. Die Standardschrift ändert sich nur, wenn Sie eine eigene Schrift registrieren und auswählen oder wenn ein Konformitätsprofil von NextPDF verlangt, eine Ersatzschrift einzubetten.
Stellen Sie früh die richtige Erwartung her: NextPDF unterstützt eine Teilmenge von HTML und CSS, nicht den vollen Umfang von beidem. Dieses Recipe behandelt genau diese unterstützte Teilmenge und beansprucht keine vollständige HTML- oder vollständige CSS-Unterstützung. Den genauen, verifizierten Status jedes Moduls finden Sie in der CSS-Support-Matrix.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“Die Methodensignatur lautet writeHtml(string $html): static. Sie ist auf dem Interface NextPDF\Contracts\PdfDocumentInterface deklariert und in NextPDF\Core\Concerns\HasTextOutput implementiert. Sie rendert auf die aktuelle Seite und legt eine Seite für Sie an, falls noch keine existiert. Die vollständige PHPDoc-Tabelle für die Methode wird aus dem Quellcode generiert.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('HTML Basic');$doc->addPage();
$doc->writeHtml('<h1>HTML Rendering in NextPDF</h1><p>Rendered with <strong>writeHtml()</strong>.</p>');
$doc->save(__DIR__ . '/out.pdf');Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Dies ist das vollständige, eigenständige Beispiel; es ist genau das, was das Test-Harness ausführt. Es entspricht examples/08-html-basic.php. Statt einen Ausgabepfad fest zu verdrahten, schreibt es an den vom Harness vorgegebenen Ort, damit das Reproduzierbarkeits-Harness das Skript zweimal ausführen und die Ergebnisse vergleichen kann.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('HTML Basic');$doc->addPage();
$html = <<<'HTML'<h1 style="color: #1E3A8A;">HTML Rendering in NextPDF</h1>
<p>NextPDF renders <strong>HTML content</strong> directly into PDF pages.This is the recommended approach for <em>mixed formatting</em>.</p>
<h2>Supported elements</h2>
<ul> <li>Headings (h1-h6)</li> <li>Paragraphs with <strong>bold</strong> and <em>italic</em></li> <li>Ordered and unordered lists</li> <li>Tables with borders and alignment</li> <li>Inline styles (color, font-size, margin)</li></ul>
<h2>Ordered list</h2>
<ol> <li>Create a Document instance</li> <li>Add pages and content</li> <li>Call save() or output()</li></ol>HTML;
$doc->writeHtml($html);
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script twice.// Honour it: do not hard-code a path, do not echo the PDF to STDOUT.$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/render-html-to-pdf.pdf');
echo "Wrote render-html-to-pdf.pdf\n";Erwartete STDOUT-Ausgabe:
Wrote render-html-to-pdf.pdfSonderfälle & Stolperfallen
Abschnitt betitelt „Sonderfälle & Stolperfallen“- Cursor-Übergabe.
writeHtml()rückt den Cursor an das Ende des gerenderten Inhalts vor. Ein nachfolgendescell()oder ein zweiteswriteHtml()setzt dort fort, nicht am Seitenanfang. - Noch keine Seite. Falls keine Seite existiert, fügt
writeHtml()vor dem Rendern eine hinzu. Rufen SieaddPage()ausdrücklich auf, wenn Sie zuerst eine bestimmte Seitengröße setzen müssen. - Element- und Verschachtelungsgrenzen. Die Streaming-Engine erzwingt eine Obergrenze von
50,000Elementen und 100 Verschachtelungsebenen (ADR-001). Ein Dokument, das diese Grenzen überschreitet, wird abgelehnt, statt stillschweigend abgeschnitten zu werden. - Nicht unterstütztes Markup. Elemente und Eigenschaften außerhalb der unterstützten Teilmenge werden ignoriert oder fallen zurück; sie lösen keinen Fehler aus. Prüfen Sie die Abdeckung anhand der CSS-Support-Matrix, bevor Sie sich auf eine Eigenschaft verlassen.
- Externe Ressourcen. Remote-Bilder und -Stylesheets unterliegen der External-Resource-Policy; die Standard-Policy ruft keine beliebigen Remote-URLs ab.
Performance
Abschnitt betitelt „Performance“Da Tokenisierung und Rendering in einem einzigen Durchlauf über Ihre Eingabe stattfinden, wachsen die Kosten linear mit der Anzahl der Tokens, also O(n). Das Standardbudget für dieses Recipe ist wall_ms: 1500, peak_mb: 96. Da die Engine die Ausgabe streamt und kein DOM im Speicher hält, richtet sich der Speicher-Peak nach der Größe des Content-Stream-Puffers und des aktiven Stil-Stacks, nicht nach der Größe des gesamten Dokuments.
Auszug aus der CSS-Support-Matrix (nur verifizierte Zeilen)
Abschnitt betitelt „Auszug aus der CSS-Support-Matrix (nur verifizierte Zeilen)“Hier erscheinen nur die mit Verified bewerteten Zeilen aus der geprüften CSS-Support-Matrix. „Verified“ bedeutet: eine Implementierung unter src/Html/ plus eine umfangreiche, eigene Fixture-Suite, die unter dem strukturellen Profil deterministisch besteht.
| W3C-Modul | Level | Status | Nachweis |
|---|---|---|---|
CSS Flexible Box Layout (css_flexbox_1) | 1 | Verified | src/Html/Flex/, tests/Unit/Html/Flex/ |
CSS Grid Layout (css_grid_1) | 1 | Verified | src/Html/Grid/, WPT-Korpus |
CSS Cascading and Inheritance (css_cascade_3) | 3 | Verified | src/Html/Cascade/, tests/Unit/Html/Cascade/ |
CSS Table (css_tables_3) | 3 | Verified | src/Html/Table/, Tabellen-Fixtures + Golden-PDFs |
CSS Fonts (css_fonts_4) | 4 | Verified | src/Html/FontFace/, tests/Unit/Html/FontFace/ |
Eigenschaften wie text-align, text-indent und color sind in der Matrix als „Claimed“ bewertet (implementiert, jedoch ohne eigene Modul-Fixture). Deshalb sind sie hier absichtlich nicht als Verified aufgeführt.
Single-Pass-Streaming-Einschränkungen (ADR-001)
Abschnitt betitelt „Single-Pass-Streaming-Einschränkungen (ADR-001)“Die HTML-Engine behält kein DOM vor. Der Zustand ist ein skalarer Cursor plus ein push/pop-Stil-Stack; Text-Knoten, die nur Whitespace enthalten, werden bei der Tokenisierung verworfen. Eine Folge daraus: Ein späteres Element kann ein früheres nicht nachträglich umgestalten, und Selektoren, die den Kontext des gesamten Baums benötigen (zum Beispiel komplexe :has()-Fälle), sind gemäß ADR-006 eingeschränkt. Planen Sie Layouts, die nur von der Dokumentreihenfolge abhängen.
Layer-Verträge (ADR-010)
Abschnitt betitelt „Layer-Verträge (ADR-010)“Parsing, Layout und Paint sind getrennte Layer. Der Parser gibt keine rohen Paint-Operatoren aus, und der Layout-Dispatch parst kein CSS; ein Überschreiten dieser Grenzen erzeugt die Kopplungsschuld, die ADR-010 verbietet. Für Recipe-Autoren bedeutet das: Der öffentliche Einstiegspunkt ist writeHtml(); greifen Sie nicht in Parser-Interna ein.
Speicherbudget für große Dokumente
Abschnitt betitelt „Speicherbudget für große Dokumente“Gemäß ADR-020 dürfen containerbezogene Formatierungskontexte (Flex, Tabelle) einen flüchtigen Teilbaum aufbauen; dieser ist auf 5,000 Knoten pro Kontext, 20 Ebenen Tiefe, eine Obergrenze von 50 MB aktivem Speicher über alle aktiven Kontexte und 10 Verschachtelungsebenen begrenzt. Außerhalb dieser Kontexte hält das Streaming-Modell keinen Baum vor. Halten Sie einzelne Tabellen und Flex-Container innerhalb der Knotengrenze, um einen vorhersehbaren Speicherverbrauch zu erreichen.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“Behandeln Sie HTML-Eingaben als nicht vertrauenswürdig. NextPDF führt keine Skripte aus, und die Standard-External-Resource-Policy ruft keine beliebigen Remote-URLs ab; die Engine selbst ist daher konservativ. Validieren oder bereinigen Sie dennoch jedes HTML, das Sie aus Benutzereingaben zusammensetzen, bevor Sie es rendern. Auch die Element- und Verschachtelungsgrenzen schützen Sie: Sie begrenzen, wie viel Arbeit ein feindseliges oder fehlerhaftes Dokument verlangen kann.
Konformität
Abschnitt betitelt „Konformität“| Aussage | Spezifikation | Klausel | reference_id |
|---|---|---|---|
| CSS Text steuert die Umwandlung von Quelltext in formatierten, zeilenumgebrochenen Text. | W3C CSS Text Level 3 | css_text_3#x1.x2.p4 | |
| Die Standardschrift für den Fließtext wird zu einer standardmäßigen Type-1-Schrift aufgelöst. | ISO 32000-2 | iso32000_2_sec9#x1.x29 |
Dieses Recipe zeigt, wie NextPDF eine unterstützte Teilmenge von HTML und CSS rendert. Es behauptet keine vollständige HTML- oder vollständige CSS-Unterstützung; den verifizierten Status pro Modul finden Sie in der CSS-Support-Matrix.
Kommerzieller Kontext
Abschnitt betitelt „Kommerzieller Kontext“Nicht zutreffend.