Zum Inhalt springen

Formularfelder zu statischem Seiteninhalt einebnen

In diesem Recipe wird ein interaktives AcroForm eingeebnet. Dabei wird der aktuelle Wert jedes Felds als gewöhnliche Grafik in den Content-Stream der Seite geschrieben; anschließend wird das AcroForm-Dictionary entfernt. Das Ergebnis ist ein nicht-interaktives Formular: eine statische Darstellung der Felder, die überall gleich aussieht – auch in einem Reader ohne Formularunterstützung (ISO 32000-2 §12.7). Das Recipe baut das Formular aus examples/30-form-fields.php auf und ruft anschließend flattenForms() auf.

Terminal-Fenster
composer require nextpdf/core:^3

Beim Einebnen wird jedes Widget auf die jeweilige Seite „gedruckt“. Textfelder werden als BT … Tj … ET-Text geschrieben. Kontrollkästchen und Optionsfelder werden als gezeichnete Pfade ausgegeben. Auswahlfelder rendern ihren ausgewählten Eintrag. Schaltflächen werden als statisches, schaltflächenartiges Kästchen gerendert. Das entspricht dem in der Spezifikation beschriebenen Modell einer statisch definierten Appearance, das verwendet wird, wenn der Feldinhalt im Voraus bekannt ist (ISO 32000-2 §12.7). Da die Werte fest eingebettet sind, wird der veraltete Mechanismus NeedAppearances nicht benötigt.

Das Profil ist structural. Das Dokument enthält eine Trailer-/ID, die der Post-Pass normalisiert, bevor zwei Läufe verglichen werden.

NextPDF\Core\Concerns\HasFormFields::flattenForms(): static ebnet jedes im Dokument angelegte Feld zu statischem Seiteninhalt ein und verwirft das AcroForm. Sind keine Felder vorhanden, bleibt der Aufruf ohne Wirkung. Intern delegiert die Methode die Arbeit an NextPDF\Form\FormFlattener.

Bauen Sie das Formular mit den Feld-Konstruktoren auf. Die einzelnen Schritte finden Sie unter Ein PDF-Formular bauen und vorausfüllen. Rufen Sie dann flattenForms() vor save() auf.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Flattened Form');
$doc->addPage();
$doc->textField(name: 'full_name', x: 20, y: 30, w: 90, h: 8, default: 'Ada Lovelace');
$doc->checkBox(name: 'agree', x: 20, y: 45, size: 5, checked: true);
// Bake the field values into the page; the AcroForm is removed.
$doc->flattenForms();
$doc->save(__DIR__ . '/flattened.pdf');
echo "Wrote flattened.pdf (no interactive fields)\n";

Das vollständige Beispiel unten baut das mehrteilige Formular aus examples/30-form-fields.php auf. Es füllt das Formular vor, ebnet es anschließend ein und schreibt die Ausgabe für den Test-Harness nach NEXTPDF_COOKBOOK_OUTPUT.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Customer Registration — Flattened');
$doc->addPage();
$doc->setFont('helvetica', 'B', 20);
$doc->cell(0, 14, 'Customer Registration (read-only copy)', newLine: true);
$doc->ln(4);
$leftMargin = 15.0;
$fieldX = 70.0;
$fieldW = 120.0;
$fieldH = 8.0;
$rowSpacing = 12.0;
$prefill = [
'full_name' => 'Ada Lovelace',
'email' => '[email protected]',
'phone' => '+44 20 7946 0000',
'company' => 'Analytical Engines Ltd',
];
$y = 40.0;
$doc->setFont('helvetica', '', 10);
foreach ($prefill as $name => $value) {
$doc->setXY($leftMargin, $y);
$doc->cell(50, $fieldH, ucwords(str_replace('_', ' ', $name)) . ':');
$doc->textField(name: $name, x: $fieldX, y: $y, w: $fieldW, h: $fieldH, default: $value);
$y += $rowSpacing;
}
$y += 6;
$doc->setXY($leftMargin, $y);
$doc->cell(0, 7, 'Newsletter');
$doc->checkBox(name: 'newsletter', x: $leftMargin + 70, y: $y, size: 5, checked: true);
// Flatten: widgets become static page content; the AcroForm is dropped.
$doc->flattenForms();
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/registration-flattened.pdf');
echo "Wrote flattened registration form\n";

Erwartete Ausgabe:

Wrote flattened registration form

Die PDF-Ausgabe zeigt dieselben Werte, jedoch ohne interaktive Felder. Ein Reader ohne Formularunterstützung rendert sie auf dieselbe Weise.

  • Das Einebnen ist nicht umkehrbar. Sobald Sie save() aufrufen, sind die interaktiven Felder nicht mehr vorhanden. Behalten Sie die nicht eingeebnete Quelle, falls Sie die Werte später noch bearbeiten müssen.
  • Aufrufreihenfolge. Führen Sie flattenForms() aus, nachdem Sie die Felder erstellt haben und bevor Sie save() aufrufen. Ein Aufruf ohne Felder bleibt ohne Wirkung und ist unbedenklich.
  • Signaturfelder werden nicht eingeebnet. Die sichtbare Darstellung eines /Sig-Felds ist die Appearance, die aus seinen CMS-SignedData erzeugt wird, kein neu renderbarer Wert. Ein erneutes Rastern würde eine statische „Geister“-Grafik erzeugen, die zu keiner überprüfbaren Signatur mehr passt. Aus diesem Grund überspringt der Flattener Signaturfelder bewusst. Ebnen Sie das Formular vor dem Signieren ein, niemals danach.
  • Wahrheitswert von Kontrollkästchen. Ein Kontrollkästchen zeigt sein Häkchen, wenn sein Wert Yes/On/1/true ist. Ein leerer oder Off-Wert rendert nur das Kästchen.
  • Schriftart für eingeebneten Text. Eingeebneter Text verwendet die aktuelle Schriftart. Ist keine Schriftart gesetzt, wird Helvetica als Fallback verwendet. Setzen Sie für CJK- oder Custom-Font-Feldwerte die gewünschte Schriftart vor flattenForms().

Das Einebnen skaliert linear mit der Anzahl der Felder. Für jedes Feld wird ein begrenzter Content-Block angehängt; anschließend wird das AcroForm-Objekt entfernt. Bei typischen Formularen bleibt der Vorgang deutlich innerhalb des Budgets von 1500 ms / 64 MB.

Das Einebnen macht Feldwerte in normalen Readern nicht bearbeitbar. Es ist eine Darstellungsänderung, keine Zugriffskontrolle. Die Werte bleiben im Seiteninhalt sichtbar, und jedes Text-Tool kann sie extrahieren. Behandeln Sie das Einebnen nicht als Schwärzung oder als Schutz sensibler Werte. Nutzen Sie für Vertraulichkeit Mit Berechtigungen verschlüsseln. Lesen Sie dort auch den Hinweis zur Reader-Kooperation, denn auch Berechtigungsbits erzwingen keine Lesebeschränkungen. Ebnen Sie niemals ein signiertes Dokument ein. Erst einebnen, dann signieren.

AussageSpecAbschnittreference_id
Ein eingeebnetes Formular ist eine nicht-interaktive (statische) Darstellung der Felder.ISO 32000-2§12.7
Die Feld-Appearance ist statisch definiert, wenn ihr Inhalt im Voraus bekannt ist.ISO 32000-2§12.7
Fest eingebrannte Appearances machen das veraltete NeedAppearances-Flag überflüssig.ISO 32000-2§12.7

NextPDF erzeugt die in den zitierten Abschnitten beschriebene statische Struktur. Es beansprucht keine pauschale ISO 32000-2-Konformität.