Przejdź do głównej zawartości

Tworzenie i wstępne wypełnianie formularza PDF

AcroForm to interaktywny formularz w pliku PDF. W tym przepisie zbudujesz taki formularz i wstępnie wypełnisz jego pola wartościami początkowymi. Cecha HasFormFields z modułu Core służy jako interfejs API do tworzenia formularzy: w tym samym wywołaniu tworzysz każde pole i podajesz jego wartość. Użyj argumentu default dla pól tekstowych, selected dla pól wyboru oraz checked dla pól wyboru typu checkbox. Po otwarciu pliku PDF pola są już wypełnione i w zgodnej przeglądarce pozostają edytowalne. Każdy, kto otworzy plik, nadal może je zmienić. Ten przepis opiera się na examples/30-form-fields.php.

Granica zakresu. Moduł Core tworzy i wypełnia pola formularza podczas tworzenia dokumentu. Nie odczytuje formularza, który już istnieje w zewnętrznym pliku PDF, ani nie scala go z mapą wartości. W tym kontekście „wypełnianie” oznacza utworzenie formularza z wartościami, a nie wczytanie i wypełnienie zewnętrznego pliku PDF. Pełny obieg (round-trip) zewnętrznego formularza to funkcja edycji Premium i server, a nie publiczny interfejs API modułu Core.

Okno terminala
composer require nextpdf/core:^3

Pole formularza AcroForm przechowuje swoją bieżącą wartość we wpisie V słownika pola (ISO 32000-2 §12.7). Może też przechowywać opcjonalną wartość domyślną we wpisie DV, do której pole powraca po uruchomieniu akcji resetowania formularza. NextPDF ustawia wpis V na podstawie wartości przekazanej do konstruktora każdego pola. Renderowanie tekstu wykorzystuje domyślny łańcuch wyglądu (DA).

Profil jest structural, ponieważ dokument zawiera tablicę /ID w sekcji trailer. Krok końcowy (post-pass) normalizuje ten zmienny identyfikator przed porównaniem.

NextPDF\Core\Concerns\HasFormFields (dołączona do klasy Document):

  • 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

Argumenty default, checked oraz selected przyjmują wartości używane do wstępnego wypełnienia.

<?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";

Poniższy pełny przykład odpowiada examples/30-form-fields.php — to formularz rejestracyjny z kilkoma sekcjami. Zapisuje wynik do NEXTPDF_COOKBOOK_OUTPUT na potrzeby środowiska testowego.

<?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";

Oczekiwane dane wyjściowe:

Wrote pre-filled registration form

Po otwarciu pliku PDF każde pole jest już wypełnione i pozostaje edytowalne.

  • Nazwy pól muszą być unikalne. Dwa pola o tej samej nazwie są w zgodnych przeglądarkach traktowane jako jedno pole logiczne ze wspólną wartością. Bywa to przydatne w przypadku pól powiązanych, ale poza takimi sytuacjami zwykle zaskakuje.
  • Semantyka grupy przycisków radio. Metoda radioButton() przypisuje każdą opcję do grupy group. Zaznaczona jest opcja, której value odpowiada wartości grupy. W danej chwili w każdej grupie aktywna jest tylko jedna opcja.
  • maxLen to wskazówka. Opcja maxLen ogranicza długość danych wprowadzanych w zgodnych przeglądarkach. Nie ogranicza przechowywanej wartości, którą wpisujesz wstępnie.
  • W API współrzędne odnoszą się do lewego górnego rogu. Cecha przelicza je na układ współrzędnych PDF z początkiem w lewym dolnym rogu, więc przekazuj współrzędne lewego górnego rogu, tak jak pokazano w przykładzie.
  • Brak wypełniania zewnętrznych plików PDF. Żadna metoda modułu Core nie wczytuje istniejącego formularza innej firmy ani nie nakłada na niego mapy wartości. Zobacz granicę zakresu powyżej.

Tworzenie formularza skaluje się liniowo wraz z liczbą pól. Każde pole dodaje jedną adnotację widgetu i jeden wygląd. Kilkaset pól bez problemu mieści się w budżecie 1500 ms / 64 MB.

Wstępnie wypełnione wartości są zapisywane dosłownie w słowniku pola. Dla każdej wartości pochodzącej z niezaufanych danych wejściowych zastosuj eskejpowanie lub walidację, zanim umieścisz ją w rozpowszechnianym dokumencie. Wstępnie wypełniony formularz nie jest chroniony: każdy, kto może otworzyć plik PDF, może odczytać i zmienić te wartości. Gdy zawartość formularza jest poufna, połącz ten przepis z Szyfrowaniem z uprawnieniami i zwróć uwagę na opisane tam zastrzeżenie dotyczące współpracy przeglądarki.

StwierdzenieSpecyfikacjaKlauzulareference_id
Bieżąca wartość pola jest przechowywana we wpisie V słownika pola.ISO 32000-2§12.7
Wartość domyślna jest przechowywana we wpisie DV i jest przywracana przy resetowaniu formularza.ISO 32000-2§12.7
Formatowanie tekstu pola wykorzystuje domyślny łańcuch wyglądu DA.ISO 32000-2§12.7

NextPDF generuje strukturę AcroForm opisaną w cytowanych klauzulach. Nie deklaruje pełnej zgodności z ISO 32000-2.