martes, 21 de abril de 2015

Ideas de reporting con xDocReport y Gx-Java

Algo que me motiva es hacer aplicaciones que tengan opciones de configuración potentes, que den a los usuarios buenas posibilidades de ajustarse a diferentes escenarios, a cambiantes contextos de negocios. O sea, a lo que tenemos por estos tiempos, cada día.
Tengo la idea de que cada vez es más común y aceptado que usuarios de configuración dispongan de más recursos en este sentido, de tal forma que los sistemas se puedan ajustar y adaptar rápido a determinados cambios. Por ejemplo, cuando se necesita definir un producto nuevo o cuando cambian reglas de cálculo de una nómina.
Otra veta a explotar en este camino es el reporting. En este post les cuento un poco sobre xDocReport, una api Java que nos permite trabajar con templates diseñados por cualquier usuario, usando MS Word, insertando campos de "combinación de correspondencia" (mergefields) que asumirán los valores de un xml al momento de crear el reporte. Usaremos la sintaxis de FreeMarker para los campos en el template docx.

Bueno, lo primero: Descargar xDocReport desde aquí.
Luego crear una KB GX-Java (yo usé la XEv2) con un webpanel que llame a un procedure, copiar todos los Jar a la carpeta web y setear la Path List de la siguiente forma:


A continuación preparar el template con MS Word.
Debe quedar más o menos así:


Dejé resaltados los campos para que se aprecie bien, así que no esperen que el archivo les quede exactamente igual. Los campos se crean usando Ctrl-F9 y se completan con la opción "Editar Campo" que aparece con el click derecho. Ahí deben dejarlo de tipo MergeField y en el nombre poner el identificador o directiva que corresponda (por ejemplo ${doc.project.name}).


El xml lo podemos generar con un sdt y el método ToXml, pero en este ejemplo lo pondremos en un archivo:
<devs>
    <developer>
        <devname>ZERR</devname>
        <devlastname>Angelo</devlastname>
        <devmail>angelo.zerr@gmail.com</devmail>
    </developer>           
    <developer>
        <devname>Leclercq</devname>
        <devlastname>Pascal</devlastname>
        <devmail>pascal.leclercq@gmail.com</devmail>
    </developer>           
</devs>           
El siguiente sería el código del procedure:

&tmpString = !"C:" + chr(92) + "xDocReportFiles" + chr(92)
&fileIN  = &tmpString + !"xDocRptTemplate.docx"
&fileXml = &tmpString + !"xDocRptData.xml"
&fileOUT = &tmpString + !"xDocRptOut.docx"
java try {
// 1) Load Docx file by filling  template engine and cache it to the registry
java     java.io.InputStream in = new java.io.FileInputStream([!&fileIN!]);
java     fr.opensagres.xdocreport.document.IXDocReport report;
java     fr.opensagres.xdocreport.template.TemplateEngineKind kind = fr.opensagres.xdocreport.template.TemplateEngineKind.Freemarker;
java     report = fr.opensagres.xdocreport.document.registry.XDocReportRegistry.getRegistry().loadReport(in,kind);
// 2) Create context Java model
java     fr.opensagres.xdocreport.template.IContext context = report.createContext();
java     java.io.InputStream projectInputStream = new java.io.FileInputStream([!&fileXml!]);
java     org.xml.sax.InputSource projectInputSource = new org.xml.sax.InputSource( projectInputStream );
java     freemarker.ext.dom.NodeModel project = freemarker.ext.dom.NodeModel.parse( projectInputSource );
java     context.put( "doc", project );
// 3) Generate report by merging Java model with the Docx
java     java.io.OutputStream out = new java.io.FileOutputStream(new java.io.File([!&fileOUT!]));
java     report.process(context, out);
java     } catch (Exception e) {
java         System.out.println("Exception thrown: " + e);
java     e.printStackTrace();
java }
RESULTADO
Para ejecutar, asegurarse de que los archivos estén en el directorio que corresponda, especialmente los Jar que deben estar en la "lib" de nuestra aplicación en el Tomcat.
Si todo sale bien, aparecerá nuestro report con los datos provistos por el xml y debiera verse así:



Eso, por ahora.

Queda una lista interesante de cosas por hacer: generar data con SDTs/DataProviders, queries dinámicas con "For Xml" (usando un store proc en Sql Server), convertir a Pdf, convertir las librerías para poder usarlas con Gx-Csharp, etc..

salu2!!!