Aller au contenu

Créer et pré-remplir un formulaire PDF

Un AcroForm est le formulaire interactif contenu dans un PDF. Cette recette en crée un et pré-remplit ses champs avec des valeurs initiales. Dans le Core, le trait HasFormFields expose une API de création de formulaire : tu crées chaque champ et fournis sa valeur dans le même appel. Utilise l’argument default pour les champs de texte, selected pour les champs de choix et checked pour les cases à cocher. Le PDF s’ouvre alors avec les champs déjà remplis, qui restent modifiables dans un lecteur conforme. Toute personne qui ouvre le fichier peut encore les modifier. Cette recette s’appuie sur examples/30-form-fields.php.

Limite de portée. Le Core crée et remplit les champs de formulaire au moment où il construit le document. Il ne lit pas un formulaire qui existe déjà dans un PDF tiers et n’y fusionne pas une table de valeurs. Ici, « fill » signifie créer le formulaire avec des valeurs, et non charger et remplir un PDF externe. Le round-tripping d’un formulaire externe est une capacité Premium côté serveur, pas une API publique du Core.

Fenêtre de terminal
composer require nextpdf/core:^3

Un champ d’AcroForm conserve sa valeur courante dans l’entrée V du dictionnaire de champ (ISO 32000-2 §12.7). Il peut aussi contenir dans DV une valeur par défaut optionnelle, à laquelle il revient lorsqu’une action de réinitialisation du formulaire s’exécute. NextPDF définit V à partir de la valeur que tu passes à chaque constructeur de champ. Le rendu du texte s’appuie sur une chaîne d’apparence par défaut (DA).

Le profil est structural parce que le document porte un tableau /ID dans son trailer. La passe de post-traitement normalise cet identifiant volatil avant la comparaison.

NextPDF\Core\Concerns\HasFormFields (intégré dans 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

Les arguments default, checked et selected portent les valeurs de pré-remplissage.

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

L’exemple complet ci-dessous reflète examples/30-form-fields.php, un formulaire d’inscription comportant plusieurs sections. Il écrit dans NEXTPDF_COOKBOOK_OUTPUT pour le harnais de test.

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

Sortie attendue :

Wrote pre-filled registration form

Quand tu ouvres le PDF, chaque champ est déjà rempli et reste modifiable.

  • Les noms de champs doivent être uniques. Deux champs portant le même nom deviennent un seul champ logique, avec une valeur partagée dans les lecteurs conformes. C’est voulu pour des champs liés, mais c’est une mauvaise surprise dans le cas contraire.
  • Sémantique des groupes de boutons radio. radioButton() rattache chaque option à un group. L’option sélectionnée est celle dont la value correspond à la valeur du groupe. Une seule option par groupe est active à la fois.
  • maxLen est une indication. Une option maxLen limite la longueur de saisie dans les lecteurs conformes. Elle ne limite pas la valeur stockée que tu pré-remplis.
  • Les coordonnées sont en haut à gauche dans l’API. Le trait convertit pour toi vers l’origine en bas à gauche du PDF ; passe donc des coordonnées en haut à gauche, comme le montre l’exemple.
  • Pas de remplissage de PDF externe. Aucune méthode du Core ne charge un formulaire tiers existant pour lui appliquer une table de valeurs. Voir la limite de portée ci-dessus.

La création de formulaire évolue de façon linéaire avec le nombre de champs. Chaque champ ajoute une annotation de widget et une apparence. Quelques centaines de champs restent largement dans le budget de 1500 ms / 64 Mo.

Les valeurs pré-remplies sont écrites telles quelles dans le dictionnaire de champ. Échappe ou valide toute valeur provenant d’une entrée non fiable avant de la placer dans un document que tu distribues. Un formulaire pré-rempli n’est pas protégé : toute personne qui peut ouvrir le PDF peut lire et modifier les valeurs. Lorsque le contenu du formulaire est sensible, associe cette recette à Chiffrer avec des permissions et tiens compte de la réserve qui y figure sur la coopération du lecteur.

ÉnoncéSpécificationClausereference_id
La valeur courante du champ est stockée dans l’entrée V du dictionnaire de champ.ISO 32000-2§12.7
La valeur par défaut est stockée dans l’entrée DV et est restaurée lors de la réinitialisation du formulaire.ISO 32000-2§12.7
Le formatage du texte du champ utilise la chaîne d’apparence par défaut DA.ISO 32000-2§12.7

NextPDF produit la structure AcroForm décrite par les clauses citées. Il ne revendique pas de conformité ISO 32000-2 complète.