Objetivo proyecto
se posee un formulario xfa pdf creado con livecycle adobe con una firma digital que debe completarse automáticamente con datos provenientes de un archivo xml.
En esta primera instancia, se busca por parte del desarrollador cumplir con el objetivo de completar el formulario en forma automática.
En términos técnicos, el desarrollador debe ser capaz de leer los datos de un archivo xml donde se identifican las variables de los campos con su valor, luego acceder al archivo xfa pdf y realizar el mapeo correspondiente de campos, finalizando con guardar los cambios en el mismo archivo pdf.
El desarrollador no puede crear un nuevo archivo (formulario PDF) con los valores importados, ya que este último carece del certificado digital.
A continuación, presentamos una serie de estrategias propuestas con respecto a la ejecución de la solución.
1. La solución propuesta (web1) podría ejecutarse en el lado del servidor (backend): Una aplicación Windows, Un servicio que se ejecute en segundo plano.
2. La solución propuesta (app1) podría ser una aplicación Windows que se ejecuta en segundo plano.
La solución propuesta puede ser desarrollado en el lenguaje que el desarrollador considere conveniente.
El desarrollador puede proponer una solución superadora fuera del ámbito definido en este requerimiento.
A continuación, presentamos los campos potenciales que deseamos completar automáticamente.
1 – UCI. Este campo es numérico, sin embargo, está definido como texto en el diseño XFA.
2 – I want service in -> Aqui hay un menu desplegable con dos opciones. Se debe seleccionar al menos una opción. (English o French). no puede estar en blanco.
3 – I am Applying for one or more of the following: Cuatro opciones disponibles, se debe seleccionar al menos una opción. no puede estar en blanco. (Textbox option)
4 – El campo denominado Date: yyyy-mm-dd. Está ubicado en la última página del Pdf.
posibles valores de los campos:
1- uci: 45124563
2- i want to service in: choose english.
3- I am applying for one or more of the following: Choose Restore my status as a worker.
4- 2023-03-06
leer con atención
en esta primera etapa los valores presentados anteriormente, pueden estar almacenados en variables locales en su desarrollo propuesto.
RECUERDE
La solución propuesta tanto Web1 o App1, debe completar los campos propuestos y guardar los cambios en el mismo formulario PDF que se proporcionó.
No se puede crear un nuevo archivo Pdf.
nomenclatura de archivos:
imm5710e.pdf: Este es el formulario principal sin datos.
Imm5710e_copy1.pdf: Este es el mismo formulario, solo que esta copia permite importar datos desde un archivo XML. Este archivo se recomienda utilizar para realizar pruebas de su código.
Imm5710e_XML.xml: Este archivo contiene los datos necesarios para completar un formulario
imm5710e.pdf.
Pdf_xml.txt: Este archivo contiene la estructura completa del formulario, es decir, la ubicación física de los campos en el pdf, tipo de datos, y código xml embebido para realizar validaciones de los campos. Estos datos pueden ser visualizados y editados con Adobe LiveCycle.
Imm5710e (4).pdf: Este archivo es una aplicación completa, por ello, los datos son reales y no deben ser subido a internet.
NOTA: Se puede proveer al desarrollador una copia de un formulario completo.
RECOMENDACIONES:
Teniendo en cuenta que el formato del archivo a completar automáticamente es xfa pdf lleva un tratamiento especial con respecto a su manipulación, por ello, lenguajes como javascript no poseen las librerías desarrolladas en su totalidad para manipular estos formatos especiales. El primer inconveniente que el desarrollador experimenta está relacionado con las restricciones para escribir en el archivo con librerías convencionales como, por ejemplo: pdf-lib, pdfform, pdfjs-dist, pdftk, hummusJS. Esta restricción está dada por cuestiones de seguridad que el creador del formulario asigno. La mayoría de las librerías que se utilizan para la manipulación de archivos pdf utilizan api de bajo nivel, que requieren acceso a la estructura interna del archivo pdf, por ello, nuestro caso es muy particular considerando que el formulario pdf tiene restricciones de seguridad que no pueden ser vulnerados. Sin embargo, El software como Adobe Acrobat pro o dc con licencias validas permiten la importación de datos a través de archivos xml, la pauta es que este procedimiento es válido, sin embargo, no apto para nuestro propósito que es automatizar este proceso. El desarrollador puede explotar esta característica para proponer su potencial solución. Un detalle importante de esta característica que brinda Adobe, es la capacidad de crear un nuevo archivo con el mismo certificado digital y habilitando la importación de datos a través de un archivo XML, recuerde que este archivo está disponible para el desarrollador y el nombre es
Imm5710e_copy1.pdf.
Recomendamos la utilización de C# o C, para el desarrollo del código, por la capacidad y el soporte de librerías especializadas en la manipulación de estos formatos. El acceso a librerías que requieren el pago de licencias, puede ser contemplada en el proyecto sin el desarrollador lo considera necesario.
Una solución práctica seria la utilización del SDK de Adobe que permite la manipulación de este tipo de formato con api especializadas (manipulación de formato xfa pdf). La principal ventaja de esta arquitectura es que nodeJS and javascript es soportado, como así también otros frameworks.
NOTA: El desarrollador puede utilizar la plataforma que considere necesaria.
DATOS TÉCNICOS A tener en cuenta:
el archivo pdf fue creado con la herramienta livecycle adobe designer es 10.0, por ello, el formato real del archivo para su manipulación es xfa pdf la cual posee una codificación de variables en sub-estructuras.
EJEMPLO:
El siguiente ejemplo identifica el nombre de la variable uci en el archivo pdf.
Form1[0].Page1[0].PersonalDetails[0].ServiceIn[0].UCIClientID[0]
Se aprecia cuatro niveles de codificación para acceder al campo.
El archivo
Pdf_xml.txt contiene toda la estructura del formulario PDF, por ello, si buscamos la variable anterior en el archivo nos lleva a la línea 26318 denominada:
<ref>xfa[0].form[0].form1[0].Page1[0].PersonalDetails[0].ServiceIn[0].UCIClientID[0].dataNode</ref>
La estructura anterior es XFA que identifica el campo llamado UCIClientID. Este ejemplo es ilustrativo a fin de entender el contexto de trabajo.
Si se procede a abrir el archivo
imm5710e.pdf con una versión que permita ejecutar JavaScript, por favor, ejecute el siguiente código para acceder al valor del campo. Recuerde, si el archivo anterior esta en blanco el comando anterior devuelve NULL, en la salida estándar.
This.getField("form1[0].Page1[0].PersonalDetails[0].ServiceIn[0].UCIClientID[0]").value;
El formulario pdf posee un certificado digital para proteger el código xml embebido que posee el archivo. Sin embargo, el formulario pdf permite la importación de datos a través de un archivo xml. La característica anterior es de suma importancia dado que el certificado no se será afectado por la operación de importación de datos.
La anterior funcionalidad fue probada exitosamente en forma manual con una versión de Adobe Acrobat PRO con licencia, las versiones gratuitas de Adobe Acrobat Reader no permiten este tipo de manipulación. Destacamos que el formulario PDF solo puede ser manipulado con productos de Adobe.
Códigos de ejemplos:
en esta sección se presentan ejemplos de códigos que tienen por objetivo orientar al desarrollador en el desarrollo de la solución.
A continuación, se presenta un código en C# que permite la lectura de un campo especifico el formulario Imm5710e (4).pdf o
Imm5710e.pdf.
analizando el código.
Se utiliza la librería iTextSharp para manipular el archivo PDF.
El nombre de la variable que identifica el campo en el pdf con nombre uci, es identificado en la estructura xfa – xml como: //form1/page1/personaldetails/servicein/uciclientid
si posee el archivo original, por favor, edite el mismo agregando un nuevo valor (campo uci) de 8 dígitos y guarde los cambios. Luego proceda a ejecutar el siguiente código para visualizar los resultados.
Código:
using System;
using
iTextSharp.text.pdf;
using
iTextSharp.text.xml.xmp;
using
System.Xml;
class Program {
static void Main(string[] args) {
string pdfPath = @"C:\play\
imm5710e_copy1.pdf";
PdfReader reader = new PdfReader(pdfPath);
XfaForm xfa = new XfaForm(reader);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xfa.DomDocument.InnerXml);
string value = xmlDoc.SelectSingleNode("//form1/Page1/PersonalDetails/ServiceIn/UCIClientID").InnerText;
Console.WriteLine("UCIClientID value: " + value);
reader.Close();
}
}
El uso de la librería Itextsharp no permite la escritura de los campos en el archivo pdf, dado que no puede hacer un bypass de la contraseña del archivo pdf. Este se debe a que la librería utiliza API de bajo nivel para manipular el formulario. El programador deber buscar la librería que permita hacer la escritura de los campos, saltando la clave de seguridad.
Se adjuntó el siguiente código que demuestra el problema del uso de esta librería al tratar de escribir el valor en el campo.
//Unhandled exception.
ITextSharp.text.exceptions.BadPasswordException: PdfReader not opened with owner password
PdfReader reader = new PdfReader("C:\\play\\test1\\
3.pdf");
AcroFields form = reader.AcroFields;
// Create a data connection to load the XML data
XfaForm xfa =
form.Xfa;
xfa.FillXfaForm("C:\\play\\test1\\
1.xml");
// Merge the data with the XFA form
using (MemoryStream output = new MemoryStream())
{
PdfStamper stamper = new PdfStamper(reader, output);
stamper.AcroFields.Xfa.FillXfaForm(xfa.DomDocument.OuterXml);
stamper.Close();
reader.Close();
File.WriteAllBytes("C:\\play\\
filled_form.pdf", output.ToArray());
Nota: Si el programador puede hacer un bypass de esta validación la solución estaría en un 80% terminada.
El siguiente código permite la carga de datos de un archivo XML en el formulario principal.
Para ejecutar el siguiente código se debe acceder a la consola JavaScript.
Var pdfDoc = app.openDoc("c://play//
imm5710e_copy1.pdf");
pdfDoc.importXFAData("c://play//
imm5710e_data.xml");
app.execMenuItem("Save");
El siguiente código permite la apertura del archivo a completar, el segundo archivo almacena los datos en formato XML, e importa los datos en el formulario principal. Por último, se procede a guardar los cambios en el archivo principal.
Esta solución deberá implementarse como una solución out of Shell, que permita la importación de datos en el archivo principal y guardar los cambios.
Ante cualquier duda o consulta, no dude en comunicarse.
Gracias.
Contexto general del proyecto
Desarrollador con habilidades en manipulación de archivos xfa pdf.
Plazo de Entrega: No definido