"Attendere... Se questo messaggio non viene infine sostituito dal contenuto corretto del documento, il visualizzatore PDF potrebbe non essere in grado di visualizzare questo tipo di documento." Se una pipeline documentale ha mai acquisito moduli governativi o assicurativi, quella pagina è già nota. Non è corruzione del file: è il segnaposto che un modulo XFA dinamico mostra a qualsiasi viewer privo di un processore XFA, cosa che oggi significa quasi tutti i viewer tranne Acrobat desktop. Archivi, viewer web ed estrazione automatica vedono tutti una sola pagina inutile. HotPDF, la libreria PDF losLab per Delphi e C++Builder, affronta il problema con un percorso di conversione che trasforma i moduli XFA in documenti AcroForm nativi, visualizzabili da qualunque reader conforme.
Due modelli di modulo che si assomigliano solo in apparenza
AcroForm, definito in ISO 32000-1 §12.7, memorizza ogni campo come oggetto PDF con un'annotazione widget e uno stream di appearance; la pagina visibile è vero contenuto PDF, e i dati del modulo vi si sovrappongono. XFA adotta l'approccio opposto: il modulo è un documento XML, un pacchetto XDP trasportato nella voce /XFA del dizionario AcroForm, e le pagine visibili vengono generate all'apertura da un motore di layout XFA. In un modulo XFA dinamico, le pagine PDF presenti nel file non sono altro che il segnaposto "Attendere", perché il contenuto reale non è mai esistito come PDF.
I due modelli, nella pratica, si escludono a vicenda: un documento viene elaborato come XFA oppure come AcroForm, e gli strumenti che ignorano la voce /XFA vedono solo il guscio del segnaposto. ISO 32000-2 ha chiuso la questione deprecando completamente XFA in PDF 2.0, motivo per cui "convertiamolo in AcroForm finché possiamo" è diventato un requisito standard di ingestione, non un caso esotico.
Non tutti i moduli XFA mostrano il segnaposto, ed è per questo che le pipeline di ingestione devono classificare prima di convertire. I moduli XFA statici includono pagine PDF prerenderizzate insieme all'XML, quindi si visualizzano ovunque e si comportano solo in modo incoerente quando vengono compilati; i moduli dinamici contengono solo il segnaposto e devono essere convertiti per essere utilizzabili. Il discriminante affidabile è il documento stesso, non l'estensione del file o il mittente: un modulo che mostra contenuto reale in un viewer non Adobe ma contiene ancora una voce /XFA è statico o ibrido, mentre uno che mostra la pagina di avviso è dinamico. Classifica ogni file in ingresso in uno di questi insiemi e registra la classificazione, perché i due tipi falliscono in modo diverso a valle e un ticket su un modulo archiviato vuoto si risolve in pochi secondi quando il record di ingestione dice "XFA dinamico, convertito, 47 campi mappati, 2 avvisi".
Flattening di un documento XFA caricato in campi nativi
Il punto di ingresso della conversione HotPDF opera su un documento caricato. FlattenLoadedXFA analizza i pacchetti template e dati XFA, impagina il modulo e lo ricostruisce come veri campi AcroForm su vere pagine PDF:
var
Pdf: THotPDF;
MappedCount, I: Integer;
Warnings: TStrings;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.LoadFromFile('dynamic_xfa.pdf');
MappedCount := Pdf.FlattenLoadedXFA(True); // True = fields stay editable
Warnings := Pdf.XFAFlattenWarnings;
for I := 0 to Warnings.Count - 1 do
Log('XFA flatten warning: ' + Warnings[I]); // unmapped elements
Pdf.SaveLoadedDocument('native_acroform.pdf');
Log(Format('Mapped %d fields', [MappedCount]));
finally
Pdf.Free;
end;
end;
Tratta il valore di ritorno e l'elenco degli avvisi come parte dell'output, non come rumore di debug. La conversione è intrinsecamente con perdita: scripting XFA, campi calcolati e comportamento dinamico dei sottomoduli non hanno un equivalente AcroForm, e XFAFlattenWarnings enumera esattamente quali elementi del template non sono stati mappati. Una pipeline che archivia il file convertito senza archiviare l'elenco degli avvisi finirà prima o poi davanti alla domanda "perché la casella dei totali è vuota nella copia archiviata" senza una risposta registrata. Il parametro Editable decide se i campi AcroForm risultanti restano compilabili; passa True quando gli utenti a valle devono continuare a lavorare sul modulo, e policy equivalenti a False quando l'obiettivo è un record fisso.
La verifica di una conversione è necessariamente visuale oltre che strutturale. Apri il modulo sorgente in Acrobat desktop, l'unico viewer che esegue ancora il motore XFA, affiancato al file convertito in un viewer ordinario, e confronta valori dei campi e layout per almeno un modulo compilato rappresentativo per template. I controlli strutturali confermano che il conteggio dei campi corrisponde a MappedCount; solo l'occhio conferma che una data formattata da XFA come 2026-06-11 non sia arrivata nella copia AcroForm come valore grezzo non formattato.
Lavorare dal lato XDP
A volte l'input non è un PDF popolato ma il pacchetto XDP stesso, esportato da uno strumento di progettazione moduli o ricevuto da un sistema partner. ApplyXFAAsAcroForm salta il passaggio di caricamento e applica il pacchetto direttamente al documento corrente:
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
La stessa famiglia di chiamate copre anche la direzione di authoring, quando devi produrre XFA invece di consumarlo: AddXFAPacket allega singoli pacchetti con nome, come 'xdp' o 'config', SetXFADocument installa un payload XFA completo a stream singolo, ClearXFAPackets azzera la registrazione e AddXFASignaturePacket incorpora materiale di firma XAdES per workflow che firmano i dati XML del modulo stesso. Generare XFA nel 2026 è un requisito di nicchia, di solito imposto da un solo consumer legacy, ma quando un contratto lo richiede queste chiamate lo mantengono un dettaglio di configurazione invece di trasformarlo in uno strumento separato.
L'altro flattening: contenuto AcroForm dichiarato con precisione
"Flatten" ha un secondo significato che crea confusione ricorrente: incorporare le appearance dei campi AcroForm nello stream di contenuto della pagina in modo che non restino oggetti interattivi. HotPDF al momento non offre un'API per questa operazione, ed è meglio pianificare tenendone conto che scoprirlo a metà progetto. Ciò che la libreria offre è il blocco a livello di campo al momento della creazione, più i permessi del documento:
// Lock the value at field creation: read-only text field
Pdf.CurrentPage.AddTextField('CaseNumber', 'BC-2026-0117',
Rect(50, 700, 220, 720), 0, [ffReadOnly]);
// Belt and suspenders: restrict form filling document-wide
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.OwnerPassword := 'records-owner';
Pdf.ProtectOptions := [prPrint, prInformationCopy, prExtractContent];
// fill permission withheld: prFillAnnotations is absent from the set
Comprendi cosa questo ottiene e cosa non ottiene. Un campo di sola lettura esiste comunque come oggetto modulo: appare nel pannello dei campi del viewer, il suo valore è estraibile tramite l'API dei moduli e uno strumento che riscrive il file può cancellare il flag. I flag di permesso alzano ulteriormente la soglia, ma si basano sulla collaborazione del viewer, come riconosce la stessa ISO 32000-1. Se un regolatore richiede che un record archiviato non contenga alcun oggetto modulo, la risposta ingegneristica onesta con HotPDF oggi è rigenerare il documento, disegnando i valori dei campi come normale contenuto TextOut su un documento nuovo usando i valori caricati, invece di fingere che i flag read-only siano flattening. Ricorda che CryptKeyLength deve essere impostato prima di BeginDoc quando scegli il percorso dei permessi; i dettagli sono nell'articolo su cifratura AES-256 e permessi.
Conseguenze di archiviazione: XFA e standard di conformità
PDF/A e PDF/X rifiutano entrambi XFA in modo esplicito, quindi una pipeline di ingestione che alimenta un archivio ISO 19005 deve convertire prima di validare, e l'ordine delle operazioni è fisso: carica, FlattenLoadedXFA, salva, poi esegui il passaggio di generazione o validazione archivistica sul risultato AcroForm. Valida l'output convertito con veraPDF invece di presumere che la conversione implichi conformità; la conversione corregge il modello di modulo, non font, colore o metadati. Il comportamento dei campi lato AcroForm, trigger JavaScript, azioni submit e script di validazione, ha una propria cassetta degli attrezzi, trattata nell'articolo sui campi e le azioni AcroForm di HotPDF.
FAQ
Perché il mio modulo PDF mostra solo una pagina "Attendere"?
È un modulo XFA dinamico e il viewer non dispone di un processore XFA. Il contenuto PDF visibile è solo un segnaposto; converti il documento con FlattenLoadedXFA per ottenere pagine e campi che ogni viewer possa renderizzare.
FlattenLoadedXFA conserva calcoli e script?
No. Lo scripting XFA e la logica di layout dinamica non sono convertibili in AcroForm; i valori calcolati presenti nei dati del modulo vengono riportati come valori statici, e XFAFlattenWarnings elenca ogni elemento che non è stato possibile mappare. Rivedi l'elenco prima di fidarti dell'output.
HotPDF può rendere un modulo completamente non interattivo?
Non con un flattening a chiamata singola: non esiste un'API di content-flattening AcroForm. Combina campi ffReadOnly con restrizioni di permesso per resistenza alle manomissioni, oppure rigenera il documento con i valori disegnati come testo semplice quando zero oggetti modulo è un requisito rigido.
Riferimento prodotto
Le API di registrazione, conversione e gestione moduli XFA descritte in questo articolo fanno parte di HotPDF Component per Delphi e C++Builder; la documentazione ne segue l'evoluzione del set di funzionalità XFA nelle versioni recenti.