Pular para o conteúdo

Crie e preencha previamente um formulário PDF

Um AcroForm é o formulário interativo de um PDF. Nesta receita, você cria um formulário e preenche previamente os campos com valores iniciais. O trait HasFormFields do Core é uma API de criação de formulários: você cria cada campo e informa o valor dele na mesma chamada. Use o argumento default para campos de texto, selected para campos de escolha e checked para caixas de seleção. O PDF abre com os campos já preenchidos, e eles permanecem editáveis em um leitor compatível. Qualquer pessoa que abrir o arquivo ainda pode alterá-los. Esta receita segue examples/30-form-fields.php.

Limite de escopo. O Core cria e preenche campos de formulário enquanto monta o documento. Ele não lê um formulário já existente em um PDF de terceiros nem mescla nele um mapa de valores. Aqui, “preencher” significa criar o formulário com valores, não carregar e preencher um PDF externo. Fazer o round-trip de um formulário externo é recurso do Premium e do server, não uma API pública do Core.

Terminal window
composer require nextpdf/core:^3

Um campo de AcroForm armazena o valor atual na entrada V do dicionário de campo (ISO 32000-2 §12.7). Ele também pode armazenar um valor padrão opcional em DV, ao qual o campo retorna quando uma ação de redefinição de formulário é executada. O NextPDF define V com base no valor que você passa para cada construtor de campo. A renderização de texto usa uma string de aparência padrão (DA).

O perfil é structural porque o documento inclui um array /ID no trailer. O pós-processamento normaliza esse identificador variável antes da comparação.

NextPDF\Core\Concerns\HasFormFields (incorporado em 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

Os argumentos default, checked e selected contêm os valores usados no pré-preenchimento.

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

O exemplo completo abaixo acompanha examples/30-form-fields.php, um formulário de cadastro com várias seções. Ele grava em NEXTPDF_COOKBOOK_OUTPUT para o harness.

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

Saída esperada:

Wrote pre-filled registration form

Quando você abre o PDF, todos os campos já estão preenchidos e permanecem editáveis.

  • Os nomes de campo devem ser únicos. Dois campos que compartilham um nome passam a ser um único campo lógico com um valor compartilhado em leitores compatíveis. Isso é útil para campos vinculados e pode surpreender quando não é essa a intenção.
  • Semântica de grupo de botões de opção. radioButton() vincula cada opção a um group. A opção selecionada é aquela cujo value corresponde ao valor do grupo. Apenas uma opção por grupo fica ativa por vez.
  • maxLen é uma dica. Uma opção maxLen limita o comprimento da entrada em leitores compatíveis. Ela não limita o valor armazenado que você preenche previamente.
  • Na API, as coordenadas partem do canto superior esquerdo. O trait converte para a origem do canto inferior esquerdo do PDF para você, então passe coordenadas do canto superior esquerdo, como o exemplo mostra.
  • Sem preenchimento de PDF externo. Nenhum método do Core carrega um formulário de terceiros já existente e aplica um mapa de valores. Consulte o limite de escopo acima.

A criação de formulários escala linearmente com o número de campos. Cada campo adiciona uma anotação de widget e uma aparência. Algumas centenas de campos permanecem confortavelmente dentro do orçamento de 1500 ms / 64 MB.

Os valores preenchidos previamente são gravados literalmente no dicionário de campo. Faça escape ou valide qualquer valor de entrada não confiável antes de inseri-lo em um documento que você distribui. Um formulário pré-preenchido não está protegido: qualquer pessoa que consiga abrir o PDF pode ler e alterar os valores. Quando o conteúdo do formulário for sensível, combine esta receita com Criptografar com permissões e observe, nessa página, a ressalva sobre cooperação do leitor.

DeclaraçãoEspecificaçãoCláusulareference_id
O valor atual do campo é armazenado na entrada V do dicionário de campo.ISO 32000-2§12.7
O valor padrão é armazenado na entrada DV e é restaurado na redefinição do formulário.ISO 32000-2§12.7
A formatação do texto do campo usa a string de aparência padrão DA.ISO 32000-2§12.7

O NextPDF emite a estrutura de AcroForm descrita pelas cláusulas citadas. Ele não declara conformidade total com a ISO 32000-2.