ข้ามไปยังเนื้อหา

สร้างและกรอกข้อมูลในแบบฟอร์ม PDF ล่วงหน้า

AcroForm คือแบบฟอร์มแบบโต้ตอบภายในไฟล์ PDF ในสูตรนี้ คุณจะสร้างแบบฟอร์มดังกล่าวและใส่ค่าเริ่มต้นให้ฟิลด์ไว้ล่วงหน้า trait HasFormFields ของ Core เป็น API สำหรับการสร้างแบบฟอร์ม โดยคุณสร้างแต่ละฟิลด์และกำหนดค่าให้ฟิลด์นั้นในการเรียกเดียวกัน ใช้อาร์กิวเมนต์ default สำหรับฟิลด์ข้อความ selected สำหรับฟิลด์ตัวเลือก และ checked สำหรับเช็กบ็อกซ์ เมื่อเปิดไฟล์ PDF ฟิลด์จะมีค่ากรอกไว้แล้วและยังคงแก้ไขได้ในโปรแกรมอ่านที่สอดคล้องกับมาตรฐาน ผู้ที่เปิดไฟล์ยังคงเปลี่ยนแปลงค่าเหล่านี้ได้ สูตรนี้อ้างอิงจาก examples/30-form-fields.php เป็นหลัก

ขอบเขตการทำงาน Core สร้างและกรอกฟิลด์ของแบบฟอร์มระหว่างสร้างเอกสาร Core ไม่อ่านแบบฟอร์มที่มีอยู่แล้วจากไฟล์ PDF ภายนอก และไม่ ผสานชุดค่า (value map) เข้ากับแบบฟอร์มนั้น ในที่นี้ “fill” หมายถึง การสร้างแบบฟอร์มพร้อมค่า ไม่ใช่ การโหลดและกรอกไฟล์ PDF จากภายนอก การโหลดแบบฟอร์มจากภายนอกแล้วบันทึกกลับ (round-tripping) เป็น ความสามารถของ Premium และ server ไม่ใช่ public API ของ Core

Terminal window
composer require nextpdf/core:^3

ฟิลด์ของ AcroForm จัดเก็บค่าปัจจุบันไว้ในรายการ V ของฟิลด์ดิกชันนารี (ISO 32000-2 §12.7) และยังสามารถจัดเก็บค่าเริ่มต้นแบบไม่บังคับไว้ใน DV ซึ่งเป็นค่าที่ฟิลด์จะคืนกลับไปเมื่อมีการเรียกใช้แอ็กชันรีเซ็ตแบบฟอร์ม NextPDF กำหนด V จากค่าที่คุณส่งให้คอนสตรักเตอร์ของแต่ละฟิลด์ การเรนเดอร์ข้อความใช้สตริงรูปลักษณ์เริ่มต้น (DA)

ใช้โปรไฟล์แบบ structural เนื่องจากเอกสารมีอาร์เรย์ /ID ใน trailer ขั้นตอนหลังประมวลผล (post-pass) จะปรับตัวระบุที่เปลี่ยนแปลงได้ให้เป็นมาตรฐานก่อนการเปรียบเทียบ

NextPDF\Core\Concerns\HasFormFields (ถูกรวมเข้าใน 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

อาร์กิวเมนต์ 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 เพื่อใช้กับ 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";

ผลลัพธ์ที่คาดหวัง:

Wrote pre-filled registration form

เมื่อคุณเปิดไฟล์ PDF ทุกฟิลด์จะมีค่ากรอกไว้แล้วและยังคงแก้ไขได้

  • ชื่อฟิลด์ต้องไม่ซ้ำกัน เมื่อมีฟิลด์สองฟิลด์ที่ใช้ชื่อเดียวกัน ฟิลด์เหล่านั้นจะกลายเป็นฟิลด์เชิงตรรกะเดียวที่ใช้ค่าร่วมกันในโปรแกรมอ่านที่สอดคล้องกับมาตรฐาน พฤติกรรมนี้มีประโยชน์สำหรับฟิลด์ที่ต้องการเชื่อมโยงกัน แต่ในกรณีอื่นอาจให้ผลลัพธ์ที่ไม่คาดคิด
  • ความหมายของกลุ่มเรดิโอ radioButton() ผูกแต่ละตัวเลือกเข้ากับ group ตัวเลือกที่ถือว่าถูกเลือกคือตัวเลือกที่ value ตรงกับค่าของกลุ่ม ในแต่ละกลุ่มจะมีตัวเลือกที่ถูกเลือกอยู่ได้เพียงตัวเลือกเดียวในแต่ละครั้ง
  • maxLen เป็นเพียงคำแนะนำ โปรแกรมอ่านที่สอดคล้องกับมาตรฐานจะใช้ตัวเลือก maxLen เพื่อจำกัดความยาวของข้อมูลที่ป้อน ตัวเลือกนี้ไม่จำกัดค่าที่จัดเก็บซึ่งคุณกรอกไว้ล่วงหน้า
  • พิกัดใน API อิงจากมุมบนซ้าย trait จะแปลงเป็นจุดกำเนิดมุมล่างซ้ายของ PDF ให้คุณ ดังนั้นให้ส่งพิกัดแบบมุมบนซ้ายตามที่แสดงในตัวอย่าง
  • ไม่รองรับการกรอกไฟล์ PDF จากภายนอก Core ไม่มีเมธอดสำหรับโหลดแบบฟอร์มที่มีอยู่แล้วจากไฟล์ PDF ภายนอกและนำชุดค่า (value map) ไปใช้ ดูขอบเขตการทำงานด้านบน

ต้นทุนการสร้างแบบฟอร์มเพิ่มขึ้นแบบเชิงเส้นตามจำนวนฟิลด์ แต่ละฟิลด์เพิ่มคำอธิบายประกอบวิดเจ็ต (widget annotation) หนึ่งรายการและรูปลักษณ์ (appearance) หนึ่งรายการ ฟิลด์ไม่กี่ร้อยฟิลด์ยังคงอยู่ภายในงบประมาณ 1500 ms / 64 MB ได้โดยไม่มีปัญหา

ค่าที่กรอกไว้ล่วงหน้าจะถูกเขียนลงในฟิลด์ดิกชันนารีแบบตรงตามตัวอักษร ให้ escape หรือตรวจสอบความถูกต้องของค่าใดๆ ที่มาจากอินพุตที่ไม่น่าเชื่อถือก่อนนำไปวางในเอกสารที่จะเผยแพร่ แบบฟอร์มที่กรอกไว้ล่วงหน้าไม่มีการป้องกัน กล่าวคือผู้ที่เปิดไฟล์ 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 อย่างครบถ้วน