« 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. » Si votre pipeline documentaire a déjà ingéré des formulaires gouvernementaux ou d'assurance, vous avez rencontré cette page. Ce n'est pas de la corruption ; c'est l'espace réservé qu'un formulaire XFA dynamique affiche à tout lecteur dépourvu de processeur XFA, ce qui signifie aujourd'hui presque tous les lecteurs sauf Acrobat desktop. Archives, lecteurs web et extraction automatisée ne voient qu'une page inutile. HotPDF, bibliothèque PDF losLab pour Delphi et C++Builder, traite ce cas par un chemin de conversion qui transforme les formulaires XFA en documents AcroForm natifs que tout lecteur conforme peut afficher.
Deux modèles de formulaires qui ne se ressemblent qu'en surface
AcroForm, défini dans ISO 32000-1 §12.7, stocke chaque champ comme objet PDF avec une annotation widget et un flux d'apparence ; la page visible est du vrai contenu PDF, et les données de formulaire se posent dessus. XFA prend l'approche inverse : le formulaire est un document XML, un paquet XDP transporté dans l'entrée /XFA du dictionnaire AcroForm, et les pages visibles sont générées à l'ouverture par un moteur de mise en page XFA. Dans un formulaire XFA dynamique, les pages PDF du fichier ne sont rien d'autre que le placeholder « Please wait », parce que le vrai contenu n'a jamais existé sous forme PDF.
Les deux modèles sont mutuellement exclusifs en pratique : un document est traité soit comme XFA, soit comme AcroForm, et les outils qui ignorent l'entrée /XFA ne voient que l'enveloppe placeholder. ISO 32000-2 a tranché en dépréciant entièrement XFA de PDF 2.0, ce qui explique pourquoi « le convertir en AcroForm tant que nous le pouvons » est devenu une exigence standard d'ingestion plutôt qu'une curiosité.
Tous les formulaires XFA n'affichent pas le placeholder, d'où l'importance de classer avant de convertir. Les formulaires XFA statiques transportent des pages PDF pré-rendues avec le XML ; ils s'affichent partout et se comportent seulement de façon incohérente une fois remplis. Les formulaires dynamiques ne transportent que le placeholder et doivent être convertis pour être utilisables. Le discriminant fiable est le document lui-même, pas l'extension ou l'expéditeur : un formulaire qui rend du vrai contenu dans un lecteur non Adobe tout en portant une entrée /XFA est statique ou hybride ; un formulaire qui affiche la page d'avertissement est dynamique. Classez chaque fichier d'ingestion dans l'un de ces groupes et enregistrez la classification, car les deux échouent différemment en aval ; un ticket de support sur un formulaire archivé vide se traite en secondes quand la fiche d'ingestion dit « XFA dynamique, converti, 47 champs mappés, 2 avertissements ».
Aplatir un document XFA chargé en champs natifs
Le point d'entrée de conversion de HotPDF opère sur un document chargé. FlattenLoadedXFA parse les paquets template et data XFA, met le formulaire en page et le reconstruit comme vrais champs AcroForm sur de vraies pages 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;
Traitez la valeur de retour et la liste d'avertissements comme une partie de la sortie, pas comme du bruit de débogage. La conversion est intrinsèquement avec pertes : scripts XFA, champs calculés et comportements de sous-formulaires dynamiques n'ont pas d'équivalent AcroForm, et XFAFlattenWarnings énumère précisément les éléments de modèle qui n'ont pas pu être mappés. Un pipeline qui archive le fichier converti sans archiver la liste d'avertissements finira par affronter la question « pourquoi la boîte de total est-elle vide dans la copie archivée » sans réponse enregistrée. Le paramètre Editable décide si les champs AcroForm résultants restent remplissables ; passez True quand les utilisateurs en aval continuent à travailler avec le formulaire, et des politiques équivalentes à False quand l'objectif est un enregistrement fixe.
La vérification d'une conversion est nécessairement visuelle autant que structurelle. Ouvrez le formulaire source dans Acrobat desktop, le lecteur qui exécute encore le moteur XFA, à côté du fichier converti dans un lecteur ordinaire, et comparez valeurs de champs et mise en page pour au moins un formulaire rempli représentatif par modèle. Les contrôles structurels confirment que le nombre de champs correspond à MappedCount ; seuls des yeux confirment qu'une date que XFA formatait comme 2026-06-11 n'est pas arrivée dans la copie AcroForm comme valeur brute non formatée.
Travailler depuis le côté XDP
Parfois, l'entrée n'est pas un PDF peuplé mais le paquet XDP lui-même, exporté d'un outil de conception de formulaires ou reçu d'un système partenaire. ApplyXFAAsAcroForm évite l'étape de chargement et applique directement le paquet au document courant :
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
La même famille d'appels couvre aussi le sens auteur, lorsque vous devez produire du XFA plutôt qu'en consommer : AddXFAPacket attache des paquets nommés individuels comme 'xdp' ou 'config', SetXFADocument installe une charge XFA complète en un seul flux, ClearXFAPackets réinitialise l'enregistrement, et AddXFASignaturePacket intègre du matériau de signature XAdES pour les workflows qui signent les données XML du formulaire lui-même. Générer du XFA en 2026 est une exigence de niche, généralement imposée par un consommateur hérité, mais quand un contrat l'exige ces appels en font un détail de configuration plutôt qu'un outil séparé.
L'autre flattening : dire honnêtement ce qu'est le contenu AcroForm
« Flatten » porte un second sens qui cause une confusion récurrente : brûler les apparences des champs AcroForm dans le flux de contenu de page afin qu'aucun objet interactif ne reste. HotPDF ne fournit pas actuellement d'API pour cette opération, et il vaut mieux planifier autour de ce fait que le découvrir en plein projet. Ce que la bibliothèque offre est le verrouillage au niveau champ à la création, plus les permissions du document :
// 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
Comprenez ce que cela réalise et ne réalise pas. Un champ en lecture seule existe encore comme objet de formulaire : il apparaît dans le panneau de champs d'un lecteur, sa valeur est extractible par l'API de formulaire, et un outil qui réécrit le fichier peut effacer le flag. Les flags de permission élèvent encore la barrière mais reposent sur la coopération du lecteur, comme ISO 32000-1 le reconnaît lui-même. Si un régulateur exige qu'un enregistrement archivé ne contienne absolument aucun objet de formulaire, la réponse d'ingénierie honnête avec HotPDF aujourd'hui consiste à régénérer le document et à dessiner les valeurs de champ comme contenu TextOut ordinaire dans un document frais à partir des valeurs chargées, plutôt qu'à prétendre que des flags lecture seule sont un flattening. Rappelez-vous que CryptKeyLength doit être défini avant BeginDoc lorsque vous empruntez la route des permissions ; les détails se trouvent dans notre article sur le chiffrement AES-256 et les permissions.
Conséquences d'archivage : XFA et les standards de conformité
PDF/A et PDF/X rejettent tous deux XFA ; un pipeline d'ingestion qui alimente une archive ISO 19005 doit donc convertir avant de valider, et l'ordre des opérations est fixe : charger, FlattenLoadedXFA, enregistrer, puis exécuter la génération ou validation d'archivage sur le résultat AcroForm. Validez la sortie convertie avec veraPDF au lieu de supposer que la conversion implique la conformité ; elle corrige le modèle de formulaire, pas les polices, la couleur ou les métadonnées. Le comportement des champs côté AcroForm, déclencheurs JavaScript, actions de soumission et scripts de validation, possède sa propre boîte à outils, couverte dans l'article HotPDF sur les champs et actions AcroForm.
FAQ
Pourquoi mon formulaire PDF n'affiche-t-il qu'une page « Please wait » ?
C'est un formulaire XFA dynamique, et votre lecteur n'a pas de processeur XFA. Le contenu PDF visible n'est qu'un placeholder ; convertissez le document avec FlattenLoadedXFA pour obtenir des pages et des champs que tous les lecteurs peuvent rendre.
FlattenLoadedXFA conserve-t-il les calculs et les scripts ?
Non. Les scripts XFA et la logique de mise en page dynamique ne sont pas convertibles en AcroForm ; les valeurs calculées présentes dans les données de formulaire sont transférées comme valeurs statiques, et XFAFlattenWarnings liste chaque élément qui n'a pas pu être mappé. Relisez cette liste avant de faire confiance à la sortie.
HotPDF peut-il rendre un formulaire complètement non interactif ?
Pas par un flatten en un appel : il n'existe pas d'API d'aplatissement du contenu AcroForm. Combinez champs ffReadOnly et restrictions de permissions pour résister aux modifications, ou régénérez le document avec les valeurs dessinées comme texte ordinaire lorsque zéro objet de formulaire est une exigence dure.
Référence produit
Les API d'enregistrement XFA, de conversion et de formulaire de cet article font partie du HotPDF Component pour Delphi et C++Builder ; sa documentation suit l'ensemble de fonctions XFA tel qu'il s'est développé dans les versions récentes.