Salta ai contenuti

Appiattire i campi del modulo come contenuto statico della pagina

Questa ricetta appiattisce un AcroForm interattivo. Rende graficamente il valore corrente di ciascun campo nel flusso di contenuto della pagina come normale grafica, quindi rimuove il dizionario AcroForm. Il risultato è un modulo non interattivo: una rappresentazione statica dei campi con lo stesso aspetto ovunque, anche in un reader privo di supporto per i moduli (ISO 32000-2 §12.7). La ricetta costruisce il modulo a partire da examples/30-form-fields.php, quindi chiama flattenForms().

Terminal window
composer require nextpdf/core:^3

L’appiattimento «stampa» ciascun widget sulla pagina corrispondente. I campi di testo diventano testo BT … Tj … ET. Le caselle di controllo e i pulsanti di opzione diventano tracciati disegnati. I campi di scelta visualizzano l’elemento selezionato. I pulsanti di comando visualizzano un riquadro statico dall’aspetto di un pulsante. Questo corrisponde al modello previsto dalla specifica per un aspetto definito staticamente, usato quando il contenuto del campo è noto in anticipo (ISO 32000-2 §12.7). Poiché i valori sono incorporati, non serve il meccanismo deprecato NeedAppearances.

Il profilo è structural. Il documento contiene un /ID nel trailer, che il passaggio successivo normalizza prima di confrontare due esecuzioni.

NextPDF\Core\Concerns\HasFormFields::flattenForms(): static appiattisce tutti i campi creati nel documento trasformandoli in contenuto statico di pagina ed elimina l’AcroForm. Se non ci sono campi, non esegue alcuna operazione. Internamente delega il lavoro a NextPDF\Form\FormFlattener.

Costruire il modulo con i costruttori dei campi. Per la procedura, vedere Creare e precompilare un modulo PDF. Quindi chiamare flattenForms() prima di save().

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Flattened Form');
$doc->addPage();
$doc->textField(name: 'full_name', x: 20, y: 30, w: 90, h: 8, default: 'Ada Lovelace');
$doc->checkBox(name: 'agree', x: 20, y: 45, size: 5, checked: true);
// Bake the field values into the page; the AcroForm is removed.
$doc->flattenForms();
$doc->save(__DIR__ . '/flattened.pdf');
echo "Wrote flattened.pdf (no interactive fields)\n";

L’esempio completo seguente costruisce il modulo a più sezioni a partire da examples/30-form-fields.php. Precompila il modulo, poi lo appiattisce e scrive in NEXTPDF_COOKBOOK_OUTPUT per l’harness.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Customer Registration — Flattened');
$doc->addPage();
$doc->setFont('helvetica', 'B', 20);
$doc->cell(0, 14, 'Customer Registration (read-only copy)', newLine: true);
$doc->ln(4);
$leftMargin = 15.0;
$fieldX = 70.0;
$fieldW = 120.0;
$fieldH = 8.0;
$rowSpacing = 12.0;
$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);
$y += $rowSpacing;
}
$y += 6;
$doc->setXY($leftMargin, $y);
$doc->cell(0, 7, 'Newsletter');
$doc->checkBox(name: 'newsletter', x: $leftMargin + 70, y: $y, size: 5, checked: true);
// Flatten: widgets become static page content; the AcroForm is dropped.
$doc->flattenForms();
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
$doc->save($out !== false ? $out : __DIR__ . '/registration-flattened.pdf');
echo "Wrote flattened registration form\n";

Output previsto:

Wrote flattened registration form

Il PDF risultante mostra gli stessi valori, ma senza campi interattivi. Un reader privo di supporto per i moduli lo visualizza nello stesso modo.

  • L’appiattimento è irreversibile. Dopo la chiamata a save(), i campi interattivi scompaiono. Conservare il documento originale non appiattito nel caso in cui sia necessario modificare i valori in seguito.
  • Ordine di chiamata. Eseguire flattenForms() dopo aver creato i campi e prima di save(). Se lo si chiama in assenza di campi, non esegue alcuna operazione; questo comportamento è sicuro.
  • I campi firma non vengono appiattiti. La rappresentazione visiva di un campo /Sig è l’aspetto prodotto dai relativi CMS SignedData, non un valore ridisegnabile. Rasterizzarla nuovamente creerebbe una grafica statica «fantasma» che non corrisponderebbe più ad alcuna firma verificabile. Per questo motivo, l’appiattitore ignora deliberatamente i campi firma. Appiattire il modulo prima di firmarlo, mai dopo.
  • Valori veri per le caselle di controllo. Una casella di controllo visualizza il segno di spunta quando il suo valore è Yes/On/1/true. Un valore vuoto oppure Off visualizza solo il riquadro.
  • Font per il testo appiattito. Il testo appiattito usa il font corrente. Se non è stato impostato alcun font, viene usata Helvetica come ripiego. Per valori di campo in CJK o con font personalizzati, impostare il font desiderato prima di flattenForms().

L’appiattimento scala linearmente con il numero di campi. Per ogni campo accoda un blocco di contenuto delimitato, quindi rimuove l’oggetto AcroForm. Per i moduli tipici, rientra ampiamente nel budget di 1500 ms / 64 MB.

L’appiattimento rende i valori dei campi non modificabili nei normali reader. Si tratta di una modifica di presentazione, non di un controllo degli accessi. I valori restano visibili nel contenuto della pagina e qualsiasi strumento di estrazione del testo può estrarli. Non considerare l’appiattimento come oscuramento né come protezione di valori sensibili. Per la riservatezza, usare Cifrare con autorizzazioni. Leggere anche lì l’avvertenza sulla cooperazione del reader, poiché nemmeno i bit di autorizzazione impongono restrizioni alla lettura. Non appiattire mai un documento firmato. Prima appiattire, poi firmare.

DichiarazioneSpecificaClausolareference_id
Un modulo appiattito è una rappresentazione non interattiva (statica) dei campi.ISO 32000-2§12.7
L’aspetto del campo è definito staticamente quando il suo contenuto è noto in anticipo.ISO 32000-2§12.7
Gli aspetti incorporati rendono non necessario il flag deprecato NeedAppearances.ISO 32000-2§12.7

NextPDF produce la struttura statica descritta dalle clausole citate. Non dichiara una conformità generale a ISO 32000-2.