Создание и предварительное заполнение PDF-формы
AcroForm — это интерактивная форма в PDF. В этом рецепте вы создаёте такую форму и предварительно заполняете её поля начальными значениями. Трейт HasFormFields из Core — API для создания формы: каждое поле создаётся, а его значение задаётся в том же вызове. Для текстовых полей используйте аргумент default, для полей выбора — selected, для флажков — checked. PDF открывается с уже заполненными полями, которые в совместимых программах просмотра остаются редактируемыми. Любой пользователь, открывший файл, по-прежнему сможет изменить эти поля. Этот рецепт основан на примере examples/30-form-fields.php.
Границы области применения. Core создаёт и заполняет поля формы при построении документа. Он не считывает форму, уже существующую в стороннем PDF, и не объединяет её с картой значений. Здесь «заполнение» означает создание формы со значениями, а не загрузку и заполнение внешнего PDF. Полный цикл обработки внешней формы — это возможность Premium и server, а не публичный API Core.
Установка
Заголовок раздела «Установка»composer require nextpdf/core:^3Концептуальный обзор
Заголовок раздела «Концептуальный обзор»Поле AcroForm хранит текущее значение в записи V словаря поля (ISO 32000-2 §12.7). Необязательное значение по умолчанию может храниться в DV; к нему поле возвращается при сбросе формы. NextPDF задаёт V из значения, переданного в конструктор каждого поля. Для отрисовки текста используется строка оформления по умолчанию (DA).
Профиль — structural, потому что документ содержит массив /ID в трейлере. Постобработка нормализует этот изменяемый идентификатор перед сравнением.
Состав API
Заголовок раздела «Состав API»NextPDF\Core\Concerns\HasFormFields (подмешан в Document):
textField(string $name, float $x, float $y, float $w, float $h, string $default = '', array $options = []): staticcheckBox(string $name, float $x, float $y, float $size, bool $checked = false): staticradioButton(string $name, float $x, float $y, float $size, string $value, string $group): staticcomboBox(string $name, float $x, float $y, float $w, float $h, array $items, string $selected = ''): staticlistBox(string $name, float $x, float $y, float $w, float $h, array $items, string $selected = ''): staticbutton(string $name, float $x, float $y, float $w, float $h, string $caption, string $action = ''): static
Аргументы default, checked и selected задают значения для предварительного заполнения.
Пример кода — быстрый старт
Заголовок раздела «Пример кода — быстрый старт»<?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";Пример кода — продакшен
Заголовок раздела «Пример кода — продакшен»Полный пример ниже повторяет examples/30-form-fields.php — форму регистрации с несколькими разделами. Для тестового окружения он записывает файл в 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 — 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', '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";Ожидаемый вывод:
Wrote pre-filled registration formПри открытии PDF каждое поле уже заполнено и остаётся доступным для редактирования.
Граничные случаи и подводные камни
Заголовок раздела «Граничные случаи и подводные камни»- Имена полей должны быть уникальными. Два поля с одинаковым именем в совместимых программах просмотра становятся одним логическим полем с общим значением. Это полезно для связанных полей, но в остальных случаях может оказаться неожиданным.
- Семантика группы переключателей.
radioButton()привязывает каждый вариант кgroup. Выбранным становится тот вариант, у которогоvalueсовпадает со значением группы. В каждой группе одновременно может быть включён только один вариант. maxLen— это подсказка. ПараметрmaxLenограничивает длину ввода в совместимых программах просмотра. Он не ограничивает сохранённое значение, которым вы предварительно заполняете поле.- В API координаты отсчитываются от верхнего левого угла. Трейт сам преобразует их к принятой в PDF точке отсчёта в нижнем левом углу, поэтому передавайте координаты от верхнего левого угла, как показано в примере.
- Нет заполнения внешнего PDF. Ни один метод Core не загружает существующую стороннюю форму и не применяет к ней карту значений. См. раздел о границах области применения выше.
Производительность
Заголовок раздела «Производительность»Создание формы масштабируется линейно по числу полей. Каждое поле добавляет одну аннотацию-виджет и одно оформление. Несколько сотен полей с запасом укладываются в бюджет 1500 ms / 64 MB.
Замечания по безопасности
Заголовок раздела «Замечания по безопасности»Предварительно заполненные значения записываются в словарь поля без изменений. Экранируйте или проверяйте любое значение из недоверенного источника, прежде чем помещать его в распространяемый документ. Предварительно заполненная форма сама по себе не защищена: любой, кто может открыть PDF, может прочитать и изменить значения. Если содержимое формы конфиденциально, используйте этот рецепт вместе с Шифрованием с разрешениями и учитывайте указанную там оговорку о зависимости от программы просмотра.
Соответствие
Заголовок раздела «Соответствие»| Утверждение | Спецификация | Раздел | идентификатор ссылки (reference_id) |
|---|---|---|---|
Текущее значение поля хранится в записи V словаря поля. | ISO 32000-2 | §12.7 | |
Значение по умолчанию хранится в записи DV и восстанавливается при сбросе формы. | ISO 32000-2 | §12.7 | |
Для форматирования текста поля используется строка оформления по умолчанию DA. | ISO 32000-2 | §12.7 |
NextPDF формирует структуру AcroForm, описанную в указанных разделах. Это не является заявлением о полном соответствии ISO 32000-2.