Due moduli possono contenere gli stessi campi e comportarsi in modo del tutto diverso. Un AcroForm conserva i propri campi come normali oggetti PDF appoggiati su contenuto di pagina reale, quindi qualsiasi reader conforme lo disegna. Un modulo XFA dinamico non conserva quasi nulla come PDF: i campi, il layout, perfino la geometria delle pagine vivono in un pacchetto XML, e le pagine visibili vengono prodotte all'apertura da un motore di impaginazione che solo Adobe ha mai distribuito su larga scala. Date quel file a un visualizzatore web, a un renderer di archiviazione o a un estrattore di testo e il modulo non lo ottenete. Ottenete una sola pagina grigia che recita "Please wait... If this message is not eventually replaced by the proper contents of the document, your PDF viewer may not be able to display this type of document." Chiunque abbia acquisito pratiche pubbliche o assicurative riconosce quella pagina a colpo d'occhio
Il segnaposto non è una corruzione. È esattamente ciò che il formato prescrive quando non è presente un processore XFA, e nel 2026 questo descrive quasi ogni visualizzatore al di fuori di Acrobat desktop. La mossa pratica è quindi convertire il modulo dinamico in un semplice AcroForm prima che raggiunga qualsiasi cosa a valle. HotPDF, la libreria PDF losLab per Delphi e C++Builder, esegue quella conversione da codice, ricostruendo il modulo XML come campi nativi su pagine native
Perché i due modelli non possono coesistere
AcroForm è definito in ISO 32000-1 §12.7. Ogni campo è un oggetto PDF con un'annotazione widget e un appearance stream, la pagina è autentico contenuto PDF e i dati viaggiano sopra di essa. XFA capovolge tutto questo: il modulo è un documento XML, un pacchetto XDP memorizzato nella voce /XFA del dizionario AcroForm, e le pagine PDF di un modulo dinamico contengono il segnaposto "Please wait" e nient'altro, perché il contenuto reale non è mai stato serializzato come PDF. Un reader elabora un file secondo un modello oppure secondo l'altro. Ignorate la voce /XFA e vedete il guscio vuoto; onoratela senza un motore XFA e vedete l'avviso. ISO 32000-2 ha chiuso il dibattito eliminando XFA da PDF 2.0, ed è la ragione principale per cui "convertiamo finché siamo in tempo" è passato da caso limite a politica di acquisizione ordinaria
Prima di convertire qualsiasi cosa, classificatela, perché non tutti i file XFA mostrano il segnaposto. I moduli XFA statici portano pagine PDF pre-renderizzate accanto all'XML, quindi si visualizzano ovunque e danno problemi solo quando vengono compilati. I moduli dinamici portano soltanto il segnaposto e sono inutilizzabili finché non vengono convertiti. La cosa di cui fidarsi è il documento, mai l'estensione o il mittente. Un file che rende contenuto reale in un visualizzatore non Adobe e porta comunque una voce /XFA è statico o ibrido; un file che mostra la pagina di avviso è dinamico. Registrate in quale categoria è finito ogni file in ingresso. I due tipi si rompono in modi diversi più avanti, e un ticket su un modulo archiviato in bianco si chiude in pochi secondi quando nel registro di acquisizione si legge già "XFA dinamico, convertito, 47 campi mappati, 2 avvisi"
Convertire un documento XFA caricato in campi nativi
La conversione lavora su un documento già in memoria. FlattenLoadedXFA analizza il template XFA e i suoi pacchetti di dati, impagina il modulo e lo ricostruisce come campi AcroForm su pagine PDF reali:
var
Pdf: THotPDF;
MappedCount, I: Integer;
Warnings: TStrings;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.LoadFromFile('dynamic_xfa.pdf');
MappedCount := Pdf.FlattenLoadedXFA(True); // True = i campi restano modificabili
Warnings := Pdf.XFAFlattenWarnings;
for I := 0 to Warnings.Count - 1 do
Log('XFA flatten warning: ' + Warnings[I]); // elementi non mappati
Pdf.SaveLoadedDocument('native_acroform.pdf');
Log(Format('Mapped %d fields', [MappedCount]));
finally
Pdf.Free;
end;
end;
Il valore di ritorno e l'elenco degli avvisi sono output, non rumore di debug, quindi conservate entrambi. La conversione perde informazioni per sua natura: lo scripting XFA, i campi calcolati e il comportamento dei subform dinamici non hanno una controparte AcroForm, e XFAFlattenWarnings nomina ogni elemento del template che non è stato mappato. Archiviate il file convertito senza il suo elenco di avvisi e un giorno vi ritroverete a fissare una casella dei totali vuota in una copia archiviata, senza alcuna traccia del perché. Il flag Editable controlla se i nuovi campi restano compilabili. Passate True quando le persone continuano a lavorare sul modulo anche dopo, e bloccate i valori quando l'obiettivo è un record congelato
Verificare una conversione è in parte visivo e in parte strutturale, e servono entrambe le metà. La metà strutturale è facile: si conferma che il numero di campi corrisponda a MappedCount. La metà visiva è quella che intercetta i danni reali. Aprite il modulo di origine in Acrobat desktop, tuttora l'unico visualizzatore che esegue il motore XFA, accanto al file convertito in un reader qualsiasi, e confrontate valori e layout su almeno un esemplare compilato per ogni template. Una data che il motore XFA mostrava come 2026-06-11 può finire nella copia AcroForm come valore grezzo e non formattato, e solo i vostri occhi lo coglieranno
Quando l'input è un pacchetto XDP
Non tutti i lavori partono da un PDF popolato. A volte ricevete il pacchetto XDP da solo, esportato da uno strumento di progettazione moduli o consegnato da un sistema partner. ApplyXFAAsAcroForm elimina il passo di caricamento e applica il pacchetto direttamente al documento corrente:
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
Lo stesso gruppo di chiamate funziona anche nella direzione opposta, per il caso più raro in cui dobbiate emettere XFA anziché consumarlo. AddXFAPacket allega singoli pacchetti denominati come 'xdp' o 'config'. SetXFADocument installa in una sola chiamata un payload completo a stream unico. ClearXFAPackets cancella la registrazione così potete ricominciare, e AddXFASignaturePacket incorpora materiale XAdES per i flussi che firmano direttamente i dati XML del modulo. Produrre XFA nel 2026 è un bisogno di nicchia, quasi sempre imposto da un unico consumatore legacy che non accetta altro, ma quando un contratto lo nomina queste chiamate lo riducono a una scelta di configurazione invece che a uno strumento separato
L'altro significato del termine "flatten"
La parola "flatten" manda in confusione molte discussioni, perché nomina una seconda operazione del tutto diversa: incidere l'aspetto dei campi AcroForm nel content stream della pagina finché non resta più alcun oggetto interattivo. HotPDF oggi non ha un'API per questo, ed è meglio saperlo adesso che a metà progetto. Quello che la libreria offre in cambio è il blocco a livello di campo al momento della creazione del campo, sostenuto dai permessi del documento:
// Blocca il valore alla creazione del campo: campo di testo di sola lettura
Pdf.CurrentPage.AddTextField('CaseNumber', 'BC-2026-0117',
Rect(50, 700, 220, 720), 0, [ffReadOnly]);
// Cintura e bretelle: limita la compilazione a livello di documento
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.OwnerPassword := 'records-owner';
Pdf.ProtectOptions := [prPrint, prInformationCopy, prExtractContent];
// permesso di compilazione negato: prFillAnnotations non è nel set
Siate chiari su cosa questo vi garantisce e cosa no. Un campo di sola lettura resta un oggetto modulo. Compare nel pannello dei campi del visualizzatore, il suo valore è leggibile attraverso l'API dei moduli, e uno strumento che riscrive il file può rimuovere di nuovo il flag di sola lettura. I flag di permesso alzano l'asticella ma dipendono dalla scelta del visualizzatore di rispettarli, un limite che ISO 32000-1 dichiara senza mezzi termini. Quando un ente regolatore pretende che un record archiviato non contenga alcun oggetto modulo, la risposta onesta con HotPDF oggi è ricostruire il documento: leggete i valori, poi disegnateli come normale contenuto TextOut su una pagina nuova, invece di far passare i flag di sola lettura per un appiattimento. Una cosa da ricordare sulla via dei permessi è che CryptKeyLength va impostato prima di BeginDoc; il resto si trova nel nostro articolo su cifratura AES-256 e permessi
Cosa comporta XFA per la conformità archivistica
PDF/A e PDF/X rifiutano XFA senza appello. Una pipeline che alimenta un archivio ISO 19005 deve perciò convertire prima, e l'ordine non è negoziabile: caricamento, FlattenLoadedXFA, salvataggio, poi generazione o validazione archivistica sul risultato AcroForm. Non trattate la conversione come prova di conformità. Sistema il modello del modulo e lascia font, colore e metadati esattamente com'erano, quindi validate l'output con veraPDF prima di fidarvene. Una volta che il modulo è passato dal lato AcroForm, il suo comportamento ha una serie di controlli propria. Trigger JavaScript, azioni di invio e script di validazione sono trattati ne l'articolo HotPDF sui campi e le azioni AcroForm
Le API di registrazione XFA, conversione e moduli mostrate qui sono incluse nel componente HotPDF per Delphi per Delphi e C++Builder, la cui documentazione segue il set di funzionalità XFA man mano che è cresciuto nelle release recenti