Emisión en formato PDF

Los reportes ODT se pueden emitir en formato PDF, convirtiendo el ODT generado a PDF mediante un comando externo y enviando al cliente el documento resultante. Para ello debe estar definida la constante PHP XGAP_COMANDO_GENERACION_PDF y su valor debe ser el comando a ejecutar.

Cuando la constante está definida, se verifican otros dos valores para determinar, en cada solicitud, si la conversión se debe realizar o no:

  • Una variable PHP global con nombre $emitir_pdf. Si está definida, su valor booleano determina si la conversión se efectúa (true) o no (false).

  • Un parámetro de request con nombre xgap_conv. La conversión se efectúa si el parámetro no está presente o tiene valor 'pdf', y no si tiene cualquier otro valor. Este parámetro sólo se toma en consideración cuando $emitir_pdf no está definida.

Nótese que el comportamiento predeterminado cuando está definida la constante XGAP_COMANDO_GENERACION_PDF, si no se utiliza la variable $emitir_pdf ni el parámetro xgap_conv, es realizar la conversión.

El proceso se detalla en la figura siguiente.

ref-reporte_odt__1.png
Figura 1. Proceso de emisión de un reporte ODT
Nota La funcionalidad descripta está definida en el código de salida predeterminado, es decir que no se aplica en reportes que usan salida personalizada (/odt/configuracion/salida).

El comando de conversión

El valor de la constante XGAP_COMANDO_GENERACION_PDF debe ser un string que se ejecuta como un comando externo. Este string puede incluir, opcionalmente, los marcadores {in} y {out} para indicar las posiciones donde se deben insertar los nombres de los archivos de entrada (ODT) y de salida (PDF), respectivamente. Si no se incluye el marcador {in}, el nombre del archivo de entrada se agrega al final del comando. Si no se incluye el marcador {out}, el nombre del archivo de salida no se incorpora al comando y se asume que éste produce un archivo con el mismo nombre que el de entrada, en el mismo directorio, con la extensión .odt reemplazada por .pdf.

Nota
Notas
  • Tener en cuenta que el comando es ejecutado por el usuario de sistema con el que corre el servidor web; se debe asegurar que este usuario cuente con los permisos necesarios para poder completar correctamente la ejecución.

  • El comando se ejecuta como está definido, sin aplicar filtros ni escapar metacaracteres del shell, para que sea posible usar comandos arbitrarios. Es responsabilidad del programador o administrador (si la constante se especifica en la configuración de la aplicación) garantizar que el comando sea seguro y no contenga datos ingresados sin filtrar por el usuario usuario.

Ejemplo 1. Ejemplos de definición del comando de conversión ODT → PDF
  • Opción 1: unoconv.

    <?php define('XGAP_COMANDO_GENERACION_PDF',
            'env HOME=/tmp /usr/bin/unoconv --timeout=10 -f pdf -e SelectPdfVersion=1 -e ExportBookmarks=true -e InitialView=0 -e PageLayout=0');

    Si unoconv ya está corriendo en modo listener, lo utiliza. Si no, inicia una nueva instancia de soffice en cada invocación.

    Para que el comando unoconv ejecutado sea capaz de comunicarse con una instancia corriendo en modo servidor, es posible que esta última deba estar iniciada por el mismo usuario que corre el servidor web; por ejemplo:

    sudo -u www-data HOME=/tmp unoconv --listener &
  • Opción 2: PyODConverter y soffice en modo servidor.

    <?php define('XGAP_COMANDO_GENERACION_PDF',
            'python "' . OUT_DIR . DIR_SEP . XGAP_CONF_APLICACION . DIR_SEP . 'PyODConverter.py" {in} {out}');

    Requiere:

    • El paquete Python PyODConverter.

    • Un script Python que invoque a PyODConverter.DocumentConverter.convert() usando los nombres de archivo que recibe como parámetro (llamado PyODConverter.py en este ejemplo).

    • Una instancia de soffice aceptando pedidos o de unoconv en modo listener (mencionado anteriormente). Una forma de iniciar soffice para que acepte pedidos es la siguiente:

      sudo -u www-data HOME=/tmp soffice --headless --accept="socket,host=127.0.0.1,port=2002;urp;" &
  • Opción 3: soffice con una instancia iniciada por cada invocación

    <?php define('XGAP_COMANDO_GENERACION_PDF',
            'env HOME=/tmp /usr/bin/libreoffice -env:HOME=/tmp --headless --invisible --convert-to pdf');

    o:

    <?php define('XGAP_COMANDO_GENERACION_PDF',
            'export HOME=/tmp; /usr/bin/libreoffice --headless --invisible --convert-to pdf');