Zum Inhalt springen

PDF-Formular erstellen und vorausfüllen

Ein AcroForm ist das interaktive Formular innerhalb einer PDF-Datei. In diesem Recipe erstellen Sie ein solches Formular und füllen seine Felder mit Startwerten voraus. Der Core-Trait HasFormFields dient als API zum Erstellen von Formularen: Sie legen jedes Feld an und übergeben seinen Wert im selben Aufruf. Verwenden Sie das Argument default für Textfelder, selected für Auswahlfelder und checked für Kontrollkästchen. Die PDF-Datei öffnet sich dann mit bereits ausgefüllten Feldern; in einem konformen Reader bleiben sie bearbeitbar. Wer die Datei öffnet, kann sie weiterhin ändern. Dieses Recipe folgt examples/30-form-fields.php.

Geltungsbereich. Core erstellt und füllt Formularfelder, während es das Dokument erstellt. Es liest kein Formular, das bereits in einem Drittanbieter-PDF vorhanden ist, und spielt keine Wertezuordnung darin ein. Hier bedeutet „fill“ das Formular mit Werten erstellen, nicht ein externes PDF laden und ausfüllen. Der Round-Trip eines externen Formulars ist eine Premium- und Server-Funktion, keine öffentliche Core-API.

Terminal-Fenster
composer require nextpdf/core:^3

Ein AcroForm-Feld speichert seinen aktuellen Wert im Eintrag V des Felddictionarys (ISO 32000-2 §12.7). Es kann außerdem einen optionalen Standardwert in DV speichern, auf den das Feld zurückgesetzt wird, wenn eine Aktion zum Zurücksetzen des Formulars ausgeführt wird. NextPDF setzt V aus dem Wert, den Sie an den jeweiligen Feldkonstruktor übergeben. Das Text-Rendering verwendet einen Standard-Erscheinungsbild-String (DA).

Das Profil lautet structural, weil das Dokument ein Trailer-/ID-Array enthält. Der Post-Pass normalisiert diesen flüchtigen Identifier vor dem Vergleich.

NextPDF\Core\Concerns\HasFormFields (in Document eingemischt):

  • textField(string $name, float $x, float $y, float $w, float $h, string $default = '', array $options = []): static
  • checkBox(string $name, float $x, float $y, float $size, bool $checked = false): static
  • radioButton(string $name, float $x, float $y, float $size, string $value, string $group): static
  • comboBox(string $name, float $x, float $y, float $w, float $h, array $items, string $selected = ''): static
  • listBox(string $name, float $x, float $y, float $w, float $h, array $items, string $selected = ''): static
  • button(string $name, float $x, float $y, float $w, float $h, string $caption, string $action = ''): static

Die Argumente default, checked und selected enthalten die Vorausfüllwerte.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Pre-filled Form');
$doc->addPage();
// Text field pre-filled with a value (sets the field dictionary /V entry).
$doc->textField(name: 'full_name', x: 20, y: 30, w: 90, h: 8, default: 'Ada Lovelace');
// Choice field pre-selected.
$doc->comboBox(
name: 'country',
x: 20, y: 45, w: 90, h: 8,
items: ['United Kingdom', 'Taiwan', 'Japan'],
selected: 'Taiwan',
);
// Checkbox pre-checked.
$doc->checkBox(name: 'newsletter', x: 20, y: 60, size: 5, checked: true);
$doc->save(__DIR__ . '/prefilled-form.pdf');
echo "Wrote prefilled-form.pdf\n";

Das vollständige Beispiel unten entspricht examples/30-form-fields.php: einem Registrierungsformular mit mehreren Abschnitten. Für das Harness schreibt es an den in NEXTPDF_COOKBOOK_OUTPUT angegebenen Pfad.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Customer Registration — Pre-filled');
$doc->addPage();
$doc->setFont('helvetica', 'B', 20);
$doc->cell(0, 14, 'Customer Registration Form', newLine: true);
$doc->ln(4);
$leftMargin = 15.0;
$fieldX = 70.0;
$fieldW = 120.0;
$fieldH = 8.0;
$rowSpacing = 12.0;
// --- Personal information, pre-filled ---
$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,
options: ['maxLen' => 80],
);
$y += $rowSpacing;
}
// --- Choice field, pre-selected ---
$y += 6;
$doc->setXY($leftMargin, $y);
$doc->cell(50, $fieldH, 'Country:');
$doc->comboBox(
name: 'country',
x: $fieldX,
y: $y,
w: $fieldW,
h: $fieldH,
items: ['United States', 'United Kingdom', 'Germany', 'Japan', 'Taiwan'],
selected: 'United Kingdom',
);
// --- Checkboxes, pre-set ---
$y += $rowSpacing + 6;
$doc->setXY($leftMargin, $y);
$doc->cell(0, 7, 'Subscribe to newsletter');
$doc->checkBox(name: 'newsletter', x: $leftMargin + 70, y: $y, size: 5, checked: true);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/registration-prefilled.pdf');
echo "Wrote pre-filled registration form\n";

Erwartete Ausgabe:

Wrote pre-filled registration form

Wenn Sie die PDF-Datei öffnen, ist jedes Feld bereits ausgefüllt und weiterhin bearbeitbar.

  • Feldnamen müssen eindeutig sein. Zwei Felder, die denselben Namen verwenden, werden in konformen Readern zu einem logischen Feld mit gemeinsamem Wert. Das ist genau das, was Sie bei verknüpften Feldern möchten, andernfalls jedoch eine Überraschung.
  • Semantik von Radio-Gruppen. radioButton() bindet jede Option an eine group. Ausgewählt ist die Option, deren value dem Wert der Gruppe entspricht. Pro Gruppe ist immer nur eine Option aktiv.
  • maxLen ist ein Hinweis. Eine maxLen-Option begrenzt die Eingabelänge in konformen Readern. Sie begrenzt nicht den gespeicherten Wert, mit dem Sie das Feld vorausfüllen.
  • Koordinaten sind in der API oben links. Der Trait rechnet für Sie auf den unten links liegenden Ursprung des PDF um; übergeben Sie Koordinaten also von oben links, wie das Beispiel zeigt.
  • Kein Ausfüllen externer PDFs. Keine Core-Methode lädt ein bestehendes Drittanbieter-Formular und wendet eine Wertezuordnung darauf an. Siehe den Geltungsbereich oben.

Die Formularerstellung skaliert linear mit der Anzahl der Felder. Jedes Feld fügt eine Widget-Annotation und ein Erscheinungsbild hinzu. Einige Hundert Felder bleiben deutlich innerhalb des Budgets von 1500 ms / 64 MB.

Vorausgefüllte Werte werden wortgetreu in das Felddictionary geschrieben. Escapen oder validieren Sie jeden Wert aus nicht vertrauenswürdiger Eingabe, bevor Sie ihn in ein Dokument einsetzen, das Sie verteilen. Ein vorausgefülltes Formular ist nicht geschützt: Jede Person, die die PDF-Datei öffnen kann, kann die Werte lesen und ändern. Wenn der Formularinhalt sensibel ist, kombinieren Sie dieses Recipe mit Mit Berechtigungen verschlüsseln und beachten Sie dort den Vorbehalt, dass es auf die Kooperation des Readers ankommt.

AussageSpezifikationKlauselreference_id
Der aktuelle Wert des Feldes wird im Eintrag V des Felddictionarys gespeichert.ISO 32000-2§12.7
Der Standardwert wird im Eintrag DV gespeichert und beim Zurücksetzen des Formulars wiederhergestellt.ISO 32000-2§12.7
Die Textformatierung des Feldes nutzt den Standard-Erscheinungsbild-String DA.ISO 32000-2§12.7

NextPDF gibt die AcroForm-Struktur aus, die in den zitierten Klauseln beschrieben ist. Es beansprucht keine vollständige ISO 32000-2-Konformität.