Jacinta

De EduWiki
(Redirigido desde «Categoría:Jacinta»)
Saltar a: navegación, buscar

INTRODUCCIÓN


Actualmente se utilizan varios gestores de reports en las diferentes aplicaciones tanto de escritorio como web, con los inconvenientes que conlleva, el más importante, la dificultad de compartir informes entre las diferentes aplicaciones, esto hace que los mantenimientos sean más costosos por lo que se precisa realizar un estudio de las diferentes opciones existentes en el mercado para elegir un gestor de informes que cubra al menos las siguientes necesidades:

  • Compatibilidad de los informes entre diferentes plataformas de desarrollo
  • Posibilidad de incorporar el motor del report en las aplicaciones o de instalar un servidor de impresión
  • Buen rendimiento ante altas cargas de trabajo
  • Posibilidad de mezclar varios reports.
  • Facilidad de diseño y mantenimiento de los informes
  • Integración con las herramientas de desarrollo

Se han analizado los siguientes:

  • BIRT
  • JasperReport
  • FOP
  • jInformes

Los detalles del informe se pueden ver en Archivo:Seleccion Gestor Reportes.pdf.

Finalmente se opta por utilizar JasperReports por el motor de generación y su potencia, simplicidad y facilidad de generar los reportes en una aplicación, estando disponible en formato plugin y en aplicación de escritorio. Otro motivo de peso en la elección es que ya se está usando en las aplicaciones existentes, por lo que la curva de aprendizaje es bastante pequeña.

JasperReports

JasperReports es una librería de creación de informes que tiene la habilidad de entregar contenido enriquecido al monitor, a la impresora o a ficheros PDF, HTML, XLS, CSV y XML. Está escrito completamente en Java y puede ser usado en gran variedad de aplicaciones de Java, incluyendo J2EE o aplicaciones web, para generar contenido dinámico. Se ha desarrollado un subproyecto que es un servidor integrado para informes: JasperReports Server. Su propósito principal es ayudar a crear documentos de tipo páginas, preparados para imprimir en una forma simple y flexible. JasperReports se usa comúnmente con iReport, un front-end gráfico de código abierto para la edición de informes, si bien a partir de la versión 5.5.0 iReport ha sido sustituido por Jaspersoft Studio, un front-end gráfico de código abierto basado en Eclipse. Se encuentra bajo licencia libre GNU, por lo que es Software libre. Forma parte de la iniciativa apilada open source Lisog.



iReport

La herramienta iReport es un constructor / diseñador de informes visual, para generar ficheros XML (plantillas de informes) utilizando la herramienta de generación de informes JasperReport, escrito en Java. Este instrumento permite que los usuarios corrijan visualmente informes complejos con cartas, imágenes, subinformes, etc. iReport está además integrado conJFreeChart, una de la biblioteca gráficas OpenSource más difundida para Java. Los datos para imprimir pueden ser recuperados por varios caminos incluso múltiples uniones JDBC, TableModels, JavaBeans, XML, etc.

Diseño de Reports JasperReports para Jacinta

File:Instalacion_Jacinta.pdf

JACINTA

Es una aplicación creada para gestionar los informes creados en JasperReports y que además permite visualizarlos sin necesidad de utilizar las aplicaciones de destino.

Haciendo uso de las posibilidades que ofrece JasperReports, podemos diseñar los reports por partes y según la necesidad componer uno nuevo que haga uso de los otros, por ejemplo, podemos disponer de varias cabeceras o pies y utilizar una u otra en función de la necesidad.

Los informes se pueden clasificar en cuatro tipos, dependiendo de su finalidad:

  • Cabecera: contiene todo lo necesario para configurar el membrete del informe, que se repitirá en cada página.
  • Pie: información que aparecerá a pie de página.
  • Subreport: es un informe que, debido a sus características, irá dentro de otro informe.
  • Report: es un informe que podrá constar de cabecera, pie y subreport.

Atendiendo a criterios de racionalización del trabajo y la facilidad de control de cambios es por lo que se dicidió establecer estos tipos de modelos. La cabecera de un documento suele ser el membrete, que es el mismo en nuchas ocasiones, por lo que siendo un report independiente del informe principal lo podemos usar tantas veces como documentos lo necesiten. La información que contiene es susceptible de cambios como es el escudo, nombre de la Consejería, Centro Directivo, dirección... es más rápido realizar estos cambios ya que sobraría con hacerlos en la cabecera y no documento por documento.

Para diseñar un report no es necesario una conexión a base de datos, solamente un fichero XML con la estructura de datos, esto permite que puedan diseñarse los informes de forma paralela al desarrollo de la aplicación y por personas diferentes, disminuyendo el tiempo de desarrollo.

MANUAL DE USO

URL de enlace a Jacinta: https://jacinta.murciaeduca.es
El enlace nos lleva a la página de autenticación para acceder a Jacinta:

Jacinta1.png

Ésta es la página principal, aquí aparecen todos los reportes disponibles ordenados alfabéticamente. Sólo tenemos que pinchar en el que nos interesa para que se active (aparece resaltado en azul) y operar sobre él a través de los botones que están arriba a la derecha. Sabremos qué botones quedan activos, esto también depende del reporte que elijamos, porque quedarán resaltados en un azul más intenso, tal y como se puede comprobar en la imagen.

Jacinta.png

Una vez elegido un reporte se activarán los correspondientes botones y si nos situamos encima de aquellos que están activos aparecerá un texto descriptivo de la función que desempeñan.

Jacinta2.png Jacinta3.png Jacinta4.png Jacinta5.png Jacinta6.png

Añadir un informe

Para añadir un nuevo informe a Jacinta pinchamos en el botón correspondiente Jacinta7.png, que encontraremos activo desde el momento en que nos autenticamos, y se nos abrirá la siguiente pantalla:

Jacinta9.png

  1. Seleccionamos el archivo del nuevo informe, con extensión .jrxml, que queremos añadir a la librería de Jacinta desde la unidad donde lo tengamos guardado.
  2. Nombre identificativo del nuevo informe subido, por defecto aparece el nombre del archivo pero puede ser modificado.
  3. Seleccionamos el tipo al que pertenece el informe. En el desplegable aparecen los tipos disponibles: REPORT, SUBREPORT, CABECERA Y PIE.
  4. Pueden existir varios informes diferentes pero con un denominador común que los identifique como una característa de los moismo, por ejemplo que sean certificados, autoliquidaciones... En este apartado podemos seleccionar una familia que ya hayamos creado a través del desplegable.
  5. O bien crear otras nuevas familias pinchando en el botón '+'.
  6. Breve descripción del documento, es opcional.
  7. Si el nuevo informe es del tipo REPORT o SUBREPORT puede que lleven cabecera, en el desplegable tendremos disponibles todas las cabeceras que previamente hayamos subido a Jacinta. Así tendremos identificado el tipo de membrete que este informe en concreto lleva.
  8. Si el nuevo informe es del tipo REPORT o SUBREPORT puede que lleven pie de documento, en el desplegable tendremos disponibles todos los pies de documento que previamente hayamos subido a Jacinta.

Pinchamos en GUARDAR y ya tenemos subido a Jacinta un nuevo reporte.

A tener en cuenta: Si subimos un informe que a su vez contiene otras partes como cabecera, pie, subreporte o imágenes, debemos subir también estas partes a Jacinta. El procedimiento y acceso es el mismo explicado aquí menos para las imágenes que tenemos que acceder por otro menú, que veremos, y que funciona igual.

Imágenes

La manera de tratar las imágenes es idéntica a los informes, dispone de las mismas opciones por lo que sirven la mismas instrucciones. Accedemos al menú que está a la izquierda en la parte superior de la pantalla inicial de jacinta

Jacinta16.png

Seleccionamos la opción 'Gestión de Imágenes'

Jacinta17.png

Tendremos esta pantalla, idéntica a la de los informes, pero destinada a las imágenes:

Jacinta18.png

Editar un informe

Para editar un informe, primero tenemos que seleccionar uno de los que tenemos ya subidos clicando encima, el fondo quedará resaltado al ponerse de color azul y también quedarán activos los botones que correspondan, situados en la parte superior a la derecha de la página principal de Jacinta. Pinchamos en el botón 'Editar' Jacint11.png y a parecerá la misma pantalla que para 'Añadir un informe' pero en esta ocasión con la información que se introdujo en el momento de crearlo, más o menos detallada dependiendo de lo meticulosos que fuimos entonces.

Jacinta12.png

  1. Puede editarse la plantilla y hacer modificaciones.

Probar un informe

Seleccionamos el informe que queremos probar, pinchamos en el botón 'Probar' Jacint13.png y aparecerá la siguiente pantalla:
Jacinta13.png

  1. Se selecciona el archivo extensión .xml correspondiente para generar el documento de la unidad donde lo tengamos almacenado.
  2. Elegimos el formato de salida del documento: pdf, word, txt...

Pinchamos en generar y aparecerá el documento en el formato de salida elegido.

Descarga fichero de informe

Tenemos la posibilidad de descargar el fichero, en formato jrxml, del informe que seleccionemos: Jacinta14.png.

Eliminar fichero

Para eliminar cualquier fichero sólo tenemos que seleccionarlo y pinchar en el botón 'Eliminar' Jacinta15.png.


CASOS DE USO

LLAMADA DESDE UN PROCEDIMIENTO DE ORACLE

FUNCTION SPFunObtenerDocumentoJacinta(xml_clob CLOB, v_param VARCHAR2)
  RETURN BLOB
  IS
    bdoc_blob BLOB;
    req     UTL_HTTP.REQ;
    resp    UTL_HTTP.RESP;
    v_txt VARCHAR2(32767);
    n_param_length NUMBER;
    req_length      binary_integer := 32767;
    v_Url VARCHAR2(255);
    pi_offset pls_integer := 1;
    pi_amount pls_integer := 2048;
    raw_buf       RAW(32767);
    raw_buf_size      binary_integer := 32767;
  BEGIN
    v_Url := 'http://vm-rest.edu.carm.es:8080/jacinta/services/generadorInformes';
    /* 
    Ejemplo param
    v_param := 'listadoId=TarjetaIdentificacionDocente.jrxml&'||'chkFormat=.pdf&'||'xmlEntrada=';
    */
    n_param_length := length(v_param)+ length(xml_clob);
    req := utl_http.begin_request (url=> v_url, method => 'POST');
    utl_http.set_header (r      =>  req,
                       name   =>  'Content-Type',
                       value => 'application/x-www-form-urlencoded;
                       charset=utf-8');
    utl_http.set_header (r      =>   req,
                       name   =>   'Content-Length',
                       value  =>   n_param_length);
    utl_http.write_text (r      =>   req,
                       data   =>   v_param);
    req_length := dbms_lob.getlength(xml_clob);
    WHILE(pi_offset < req_length) LOOP
        dbms_lob.read(xml_clob, pi_amount, pi_offset, v_txt);
        utl_http.write_text(req, v_txt);
        pi_offset := pi_offset + pi_amount;
    END LOOP;
    resp := UTL_HTTP.GET_RESPONSE(req);
    IF (resp.status_code = 200) THEN
            dbms_lob.createtemporary(bdoc_blob, false);
        BEGIN
            LOOP
                utl_http.read_raw(resp, raw_buf, raw_buf_size);
                dbms_lob.writeappend (bdoc_blob, utl_raw.length(raw_buf), raw_buf);
            END LOOP;
            utl_http.end_response(resp);
        EXCEPTION
            WHEN UTL_HTTP.END_OF_BODY THEN
                utl_http.end_response(resp);
        END;
    ELSE
        utl_http.end_response(resp);
    END IF;
    RETURN bdoc_blob;
  EXCEPTION
    WHEN OTHERS THEN
        utl_http.end_response(resp);
        RETURN bdoc_blob;
  END;

LLAMADA DESDE .NET

public string HttpPostCertSolicitud()
{
      //Certificado de Solicitud de Expediente
       string URI = TiposGenerales.GetDescripcionValor("PARAMS","JACIN");
      Parameters = TiposGenerales.GetDescripcionValor("TASAS", "SOLEX");
      MsgOut sComando = new MsgOut("GenerarCertSoliciXml");
      sComando.AddParam("CodigoCentro", _mainConfig.IDCentro);
      sComando.AddParam("CodigoTitulo", m_drFila["CODIGOTITULO"].ToString());
      sComando.AddParam("CodigoEnsenianzaMec", m_drFila["CodigoEnsenianzaMEC"].ToString());
      sComando.AddParam("CodigoEnsenianzaCarm", m_drFila["CodigoEnsenianzaCARM"].ToString());
      sComando.AddParam("IdAlumno", _IdAlumno);
      MsgIn sResult = _oCommManager.Get(sComando);
      this.Cursor = System.Windows.Forms.Cursors.Default;
       if ((sResult.RC == Result.OK) && (sResult.DS.Tables[0].Rows.Count  > 0))
      {
          documentoXml = sResult.DS.Tables[0].Rows[0]["Xml"];
          Parameters += HttpUtility.UrlEncode(documentoXml.ToString());
          string Out = String.Empty;
          System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
          try
            {
               req.Method = "POST";
               req.Timeout = 100000;
               req.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
               byte[] sentData = Encoding.UTF8.GetBytes(Parameters);
               req.ContentLength = sentData.Length;
               using (System.IO.Stream sendStream = req.GetRequestStream())
               {
                  sendStream.Write(sentData, 0, sentData.Length);
                  sendStream.Close();
               }
                  System.Net.WebResponse res = req.GetResponse();
                   System.IO.Stream ReceiveStream = res.GetResponseStream();
                  //Pasamos de char a byte
                  byte[] buffer = new byte[4096];
                  byte[] result;
                  using (MemoryStream memoryStream = new MemoryStream())
                  {
                     int count = 0;
                     do
                     {
                        count = ReceiveStream.Read(buffer, 0, buffer.Length);
                        memoryStream.Write(buffer, 0, count);
                     } while (count != 0);
                     result = memoryStream.ToArray();
                  }
                  //Pasamos de bytes a char
                   System.IO.MemoryStream msAux = new System.IO.MemoryStream(result);
                   string adjuntoFileName = GICForm._mainConfig.PathImagenes + Guid.NewGuid() + ".pdf";//GICForm._mainConfig.PathImagenes + "CertificadoSolicitud.pdf";
                  using (FileStream fs = File.Create(adjuntoFileName))
                  {
                        const int blockSize = 1024;
                        byte[] buffer2 = new byte[blockSize];
                        int numBytes;
                        while ((numBytes = msAux.Read(buffer2, 0, blockSize)) > 0)
                        {
                            fs.Write(buffer2, 0, numBytes);
                        }
                   }
                   System.Diagnostics.Process.Start(adjuntoFileName);
                   //System.IO.File.Delete(adjuntoFileName);
                }
                catch (ArgumentException ex)
                {
                    Out = string.Format("HTTP_ERROR :: The second HttpWebRequest object has raised an Argument Exception as 'Connection' Property is set to 'Close' :: {0}", ex.Message);
                }
                catch (WebException ex)
                {
                     Out = string.Format("HTTP_ERROR :: WebException raised! :: {0}", ex.Message);
                }
                catch (Exception ex)
                {
                     Out = string.Format("HTTP_ERROR :: Exception raised! :: {0}", ex.Message);
                }
                return Out;
            }
      else
      {
         MessageBox.Show("No se ha podido recuperar el documento");
         return null;
      }
}

LLAMADA DESDE JAVA

Código java para generar una llamada a Jacinta, muestra como componer un XML y realizar la llamada. Se muestra el fichero .java también por si queda mas claro. File:TasasAction.java.pdf

/**
* Generar documento de la tasa.
* 
* @param request
* @param response
* @param application
* @return
* @throws Exception
*/
public String documento(HttpServletRequest request, HttpServletResponse response, ServletContext application)
throws Exception {
String grado = request.getParameter("grado");
String idTasa = request.getParameter("idTasa");
HttpClient client = new DefaultHttpClient();
  HttpPost post = new HttpPost(parametrosAplicacionService.parametroAplicacion(ParametrosAplicacionService.PARAM_URL_JACINTA));
  List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
  nameValuePairs.add(new BasicNameValuePair("listadoId", "AutoliquidacionTasa.jrxml"));
  nameValuePairs.add(new BasicNameValuePair("chkFormat", ".pdf"));
  nameValuePairs.add(new BasicNameValuePair("xmlEntrada", generarXMLDoc(idTasa)));
  post.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
  HttpResponse res = client.execute(post);
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment; filename=tasa" + grado + System.currentTimeMillis() + ".pdf");
IOUtils.copy(res.getEntity().getContent(), response.getOutputStream());
return FrontController.SERVICE;
}
/**
* Genera el XML necesario para generar el documento de la tasa.
* 
* @param idTasa
* @return
* @throws Exception
*/
private String generarXMLDoc(String idTasa) throws Exception {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Elemento AUTOLIQUIDACIONTASAS
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("AUTOLIQUIDACIONTASAS");
doc.appendChild(rootElement);
// Elemento PARAMCABECERA
Element paramCabecera = doc.createElement("PARAMCABECERA");
rootElement.appendChild(paramCabecera);
// Datos de la tasa
ExecuteCommand cmd = new ExecuteCommand();
ReadXML xml = new ReadXML();
cmd.setCommand("ComprobarGenTasa");
cmd.addParameter("IdTasa", idTasa);
Hashtable<String, Object> hshDatosTasa = xml.getResult(cmd.execute());
if (hshDatosTasa.containsKey("TASASALUMNOS")) {
Map<String, String> datosTasa = ((DataTable) hshDatosTasa.get("TASASALUMNOS")).getData().get(0);
// Parametros
int i = 1;
paramCabecera.appendChild(crearParam(doc, i++, "ESCUDO_CARM", "escudoColor.png"));
paramCabecera.appendChild(crearParam(doc, i++, "CONSEJERIA", nombreConsejeria));
paramCabecera.appendChild(crearParam(doc, i++, "MODELOTASA", obtenerValorParaXML(datosTasa, "TAS_ID")));
paramCabecera.appendChild(crearParam(doc, i++, "TIPOTASA", obtenerValorParaXML(datosTasa, "TAS_ID")));
paramCabecera.appendChild(crearParam(doc, i++, "CODIGO_TASA", obtenerValorParaXML(datosTasa, "TAS_N28")));
paramCabecera.appendChild(crearParam(doc, i++, "NIFCIF", obtenerValorParaXML(datosTasa, "SPS_NIF")));
paramCabecera.appendChild(crearParam(doc, i++, "NOMBRE", obtenerValorParaXML(datosTasa, "SPS_NOMBRE")));
paramCabecera.appendChild(crearParam(doc, i++, "TELEFONO", obtenerValorParaXML(datosTasa, "SPS_TELEFONO")));
paramCabecera.appendChild(crearParam(doc, i++, "DIRECCION", obtenerValorParaXML(datosTasa, "SPS_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "NIFCIFREP", obtenerValorParaXML(datosTasa, "REP_NIF")));
paramCabecera.appendChild(crearParam(doc, i++, "NOMBREREP", obtenerValorParaXML(datosTasa, "REP_NOMBRE")));
paramCabecera.appendChild(crearParam(doc, i++, "TELEFONOREP", obtenerValorParaXML(datosTasa, "REP_TELEFONO")));
paramCabecera.appendChild(crearParam(doc, i++, "DIRECCIONREP", obtenerValorParaXML(datosTasa, "REP_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "CODIGOAUTOLIQ", obtenerValorParaXML(datosTasa, "TAS_CODIGO")));
paramCabecera.appendChild(crearParam(doc, i++, "FECHDEVENGO", obtenerValorParaXML(datosTasa, "TAS_FECHADEVENGO")));
paramCabecera.appendChild(crearParam(doc, i++, "DESCAUTOLIQ", obtenerValorParaXML(datosTasa, "TAS_DESHI")));
paramCabecera.appendChild(crearParam(doc, i++, "DESCIMPORTE", obtenerValorParaXML(datosTasa, "TAS_IMPTOTAL")));
paramCabecera.appendChild(crearParam(doc, i++, "IMPORTE", obtenerValorParaXML(datosTasa, "TAS_IMPTOTAL")));
paramCabecera.appendChild(crearParam(doc, i++, "TOTALCUOTAS", obtenerValorParaXML(datosTasa, "TAS_IMPCUOTA")));
paramCabecera.appendChild(crearParam(doc, i++, "BENEFICIOFISCAL", obtenerValorParaXML(datosTasa, "TAS_IMPBENFISCAL")));
paramCabecera.appendChild(crearParam(doc, i++, "OTROSAJUSTES", obtenerValorParaXML(datosTasa, "REP_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "INGACUENTA", obtenerValorParaXML(datosTasa, "REP_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "IVA", obtenerValorParaXML(datosTasa, "TAS_IMPIVA")));
paramCabecera.appendChild(crearParam(doc, i++, "EXENCIONIVA", obtenerValorParaXML(datosTasa, "REP_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "DEMORA", obtenerValorParaXML(datosTasa, "REP_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "REFADMIN", obtenerValorParaXML(datosTasa, "REP_DIRECCION")));
paramCabecera.appendChild(crearParam(doc, i++, "CODIGO128", obtenerValorParaXML(datosTasa, "CODIGO28")));
paramCabecera.appendChild(crearParam(doc, i++, "ATRIBUTO", obtenerValorParaXML(datosTasa, "TAS_ATRIBUTO")));
paramCabecera.appendChild(crearParam(doc, i++, "IMPINGRESAR", obtenerValorParaXML(datosTasa, "TAS_IMPTOTAL")));
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
transformer.transform(new DOMSource(doc), result);
return sw.toString();
}
/**
* Crea un nodo parámetro con formato:
* 
* <PARAM3 id="MODELOTASA">T963.4</PARAM3>
* 
* @param doc
* @param indice
* @param nombre
* @param valor
* @return
*/
private Element crearParam(Document doc, int indice, String nombre, String valor) {
Element param = doc.createElement("PARAM" + indice);
Attr attr = doc.createAttribute("id");
attr.setValue(nombre);
param.setAttributeNode(attr);
param.appendChild(doc.createTextNode(valor));
return param;
}
/**
* 
* @param datos
* @param valor
* @return
*/
private String obtenerValorParaXML(Map<String, String> datos, String valor) {
if (datos.containsKey(valor)) {
return datos.get(valor);
} else  {
return "";
}
}