"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 su canalización de documentos alguna vez ingirió formularios gubernamentales o de seguros, ya conocen esta página. No es corrupción; es el marcador de posición que un formulario XFA dinámico muestra a cualquier visor que carece de procesador XFA, lo que hoy significa casi todos los visores excepto Acrobat de escritorio. Archivos, visores web y extracción automatizada ven una sola página inútil. HotPDF, la biblioteca PDF de losLab para Delphi y C++Builder, aborda esto con una ruta de conversión que transforma formularios XFA en documentos AcroForm nativos que cualquier lector conforme puede mostrar.
Dos modelos de formulario que sólo se parecen por fuera
AcroForm, definido en ISO 32000-1 §12.7, almacena cada campo como un objeto PDF con una anotación widget y un stream de apariencia; la página que se ve es contenido PDF real, y los datos del formulario viajan encima. XFA toma el enfoque opuesto: el formulario es un documento XML, un paquete XDP transportado en la entrada /XFA del diccionario AcroForm, y las páginas visibles se generan al abrir mediante un motor de layout XFA. En un formulario XFA dinámico, las páginas PDF del archivo no son más que el marcador "Please wait", porque el contenido real nunca existió como PDF.
En la práctica, los dos modelos son mutuamente excluyentes: un documento se procesa como XFA o como AcroForm, y las herramientas que ignoran la entrada /XFA sólo ven el cascarón del marcador. ISO 32000-2 cerró la discusión al desaprobar XFA por completo en PDF 2.0, por eso "convertirlo a AcroForm mientras todavía se pueda" se volvió un requisito estándar de ingesta más que algo exótico.
No todos los formularios XFA muestran el marcador, y por eso las canalizaciones de ingesta deben clasificar antes de convertir. Los formularios XFA estáticos llevan páginas PDF prerenderizadas junto con el XML, de modo que se muestran en todas partes y sólo se comportan de forma inconsistente cuando se llenan; los formularios dinámicos llevan sólo el marcador y deben convertirse para ser utilizables. El discriminador confiable es el propio documento, no la extensión de archivo ni el remitente: un formulario que renderiza contenido real en un visor que no es Adobe pero todavía lleva una entrada /XFA es estático o híbrido, y uno que muestra la página de advertencia es dinámico. Clasifiquen cada archivo de entrada en uno de esos grupos y registren la clasificación, porque los dos tipos fallan de formas distintas aguas abajo y un ticket de soporte sobre un formulario archivado en blanco se responde en segundos cuando el registro de ingesta dice "dynamic XFA, converted, 47 fields mapped, 2 warnings".
Aplanar un documento XFA cargado hacia campos nativos
El punto de entrada de conversión de HotPDF opera sobre un documento cargado. FlattenLoadedXFA analiza los paquetes de plantilla y datos XFA, compone el formulario y lo reconstruye como campos AcroForm reales sobre páginas PDF reales:
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;
Traten el valor de retorno y la lista de advertencias como parte de la salida, no como ruido de depuración. La conversión es inherentemente con pérdida: scripts XFA, campos calculados y comportamiento dinámico de subformularios no tienen equivalente AcroForm, y XFAFlattenWarnings enumera exactamente qué elementos de plantilla no pudieron mapearse. Una canalización que archiva el archivo convertido sin archivar la lista de advertencias terminará enfrentando la pregunta "por qué la caja de totales está vacía en la copia archivada" sin una respuesta registrada. El parámetro Editable decide si los campos AcroForm resultantes permanecen rellenables; pasen True cuando los usuarios posteriores continúen trabajando con el formulario, y políticas equivalentes a False cuando el objetivo sea un registro fijo.
La verificación de una conversión debe ser visual además de estructural. Abran el formulario fuente en Acrobat de escritorio, el único visor que todavía ejecuta el motor XFA, junto al archivo convertido en cualquier visor ordinario, y comparen valores de campos y layout para al menos un formulario lleno representativo por plantilla. Las comprobaciones estructurales confirman que el conteo de campos coincide con MappedCount; sólo los ojos confirman que una fecha que XFA formateó como 2026-06-11 no llegó a la copia AcroForm como un valor crudo sin formato.
Trabajar desde el lado XDP
A veces la entrada no es un PDF poblado sino el propio paquete XDP, exportado desde una herramienta de diseño de formularios o recibido desde un sistema socio. ApplyXFAAsAcroForm omite el paso de carga y aplica el paquete directamente al documento actual:
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
La misma familia de llamadas también cubre la dirección de autoría, cuando necesitan producir XFA en lugar de consumirlo: AddXFAPacket adjunta paquetes individuales con nombre como 'xdp' o 'config', SetXFADocument instala una carga XFA completa en un único stream, ClearXFAPackets reinicia el registro, y AddXFASignaturePacket embebe material de firma XAdES para flujos de trabajo que firman los datos XML del formulario. Generar XFA en 2026 es un requisito de nicho, normalmente impulsado por un consumidor heredado, pero cuando un contrato lo exige estas llamadas lo mantienen como detalle de configuración en lugar de herramienta separada.
El otro flattening: contenido AcroForm, explicado con honestidad
"Flatten" tiene un segundo significado que causa confusión recurrente: quemar las apariencias de campos AcroForm en el stream de contenido de página para que no queden objetos interactivos. HotPDF no proporciona actualmente una API para esa operación, y es mejor planear con ese dato que descubrirlo a mitad del proyecto. Lo que la biblioteca sí ofrece es bloqueo a nivel de campo al crearlo, más permisos de 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
Entiendan qué logra y qué no logra esto. Un campo de sólo lectura sigue existiendo como objeto de formulario: aparece en el panel de campos del visor, su valor puede extraerse mediante la API de formularios y una herramienta que reescriba el archivo puede limpiar el flag. Los flags de permiso suben más la barrera, pero descansan en la cooperación del visor, tal como reconoce ISO 32000-1. Si un regulador exige que un registro archivado no contenga ningún objeto de formulario, la respuesta de ingeniería honesta con HotPDF hoy es regenerar el documento, dibujando los valores de campo como contenido TextOut ordinario en un documento nuevo usando los valores cargados, no fingir que los flags de sólo lectura son flattening. Recuerden que CryptKeyLength debe configurarse antes de BeginDoc cuando toman la ruta de permisos; los detalles viven en nuestro artículo de cifrado AES-256 y permisos.
Consecuencias de archivo: XFA y los estándares de cumplimiento
PDF/A y PDF/X rechazan XFA por completo, así que una canalización de ingesta que alimenta un archivo ISO 19005 debe convertir antes de validar, y el orden de operaciones es fijo: cargar, FlattenLoadedXFA, guardar, y luego ejecutar la generación archivística o la pasada de validación sobre el resultado AcroForm. Validan la salida convertida con veraPDF en lugar de asumir que conversión implica cumplimiento; la conversión corrige el modelo de formulario, no fuentes, color ni metadatos. El comportamiento de campos del lado AcroForm, disparadores JavaScript, acciones de envío y scripts de validación, tiene su propio conjunto de herramientas, cubierto en el artículo de campos y acciones AcroForm de HotPDF.
FAQ
¿Por qué mi formulario PDF sólo muestra una página "Please wait"?
Es un formulario XFA dinámico, y su visor no tiene procesador XFA. El contenido PDF visible es sólo un marcador; conviertan el documento con FlattenLoadedXFA para obtener páginas y campos que todos los visores puedan renderizar.
¿FlattenLoadedXFA conserva cálculos y scripts?
No. Los scripts XFA y la lógica de layout dinámico no son convertibles a AcroForm; los valores calculados presentes en los datos del formulario se trasladan como valores estáticos, y XFAFlattenWarnings lista cada elemento que no pudo mapearse. Revisen esa lista antes de confiar en la salida.
¿HotPDF puede hacer un formulario completamente no interactivo?
No mediante un flatten de una sola llamada: no hay API de aplanamiento de contenido AcroForm. Combinen campos ffReadOnly con restricciones de permisos para resistencia a manipulación, o regeneren el documento con los valores dibujados como texto plano cuando cero objetos de formulario sea un requisito duro.
Referencia de producto
Las API de registro, conversión y formularios XFA de este artículo forman parte de HotPDF Component para Delphi y C++Builder; su documentación rastrea el conjunto de funciones XFA conforme ha crecido en releases recientes.