3.2.14

Tablas que no se muestran con FOP 0.20

FOP es la implementación de Apache del estándar XSL (también conocido como XSL-FO). Soporta varios formatos de salida, pero es habitual usarlo sólo para generar PDFs.

Las primeras versiones usables fueron las 0.20.4 y 0.20.5, allá por 2003. La siguiente release estable fue la 0.93 en 2007, y prácticamente se rehizo desde cero. Dado que las versiones 0.20 no implementaban correctamente el estándar XSL, a la hora de crear una plantilla para generar un PDF con un formato muy concreto, se tenía que recurrir a truquillos, trampas y (por qué no llamarlas así) ñapas. Con la llegada de la 0.93, al corregir muchos de los defectos de las versiones anteriores, las plantillas desarrolladas para las 0.20, no eran adecuadas para las modernas versiones, y los PDFs generados tenían una apariencia diferente a la deseada. La solución ideal, por supuesto, es adaptar dichas plantillas a la nueva versión. Pero claro, eso supone dedicar tiempo. Tiempo al que una empresa no ve rendimiento, ya que, después de todo, se va a modificar algo que ya funciona. Así que el estancarse en una versión concreta y antigua de FOP, se ha convertido en algunos sitios, en un dato del problema.

El problema aparece cuando hay que modificar o crear una plantilla que funcione con las 0.20, y la mayoría de información disponible en la red (al menos, la que aparece en primer lugar buscando con Google), se refiere a versiones más modernas. O también, cuando uno reaprovecha ese XSL que genera un PDF tan chulo con FOP 1.1, y al usarla con nuestro 0.20, el resultado es desolador.

Bien, recientemente sufrí uno de estos casos, cuando con una plantilla que funcionaba bien con la 0.94, al usarla con la 0.20.4, desaparecían tablas enteras. No se renderizaban en el PDF. Y el log no daba ninguna pista de por qué (no había errores).

El problema está en que la versión 0.20.4 (no sé si ocurre lo mismo con la 0.20.5), no soporta el autoajuste del ancho de las columnas. Es decir, hay que indicar de forma explícita el ancho de cada columna. Si no, la tabla no se mostrará. Veamos un ejemplo muy simple.


<fo:table>
  <fo:table-body>

    <fo:table-row>
      <fo:table-cell>
        (...)
      </fo:table-cell>
      <fo:table-cell>
        (...)
      </fo:table-cell>
    </fo:table-row>
    
    (...)
    
  </fo:table-body>
</fo:table>

He obviado algunas cosas, ya que sólo nos interesa la estructura de las etiquetas de tabla. Este fragmento de código podría formar parte de un XSL que funciona con versiones de FOP superiores o iguales a la 0.93. Sin embargo, con la 0.20.4, no mostrará nada de nada. Para que lo haga, debemos fijar el ancho de cada columna de la tabla:


<fo:table>

  <fo:table-column column-width="proportional-column-width(50)"/>
  <fo:table-column column-width="proportional-column-width(50)"/>

  <fo:table-body>

    <fo:table-row>
      <fo:table-cell>
        (...)
      </fo:table-cell>
      <fo:table-cell>
        (...)
      </fo:table-cell>
    </fo:table-row>
    
    (...)
    
  </fo:table-body>
</fo:table>

En este ejemplo, se establece que cada columna ocupe la mitad del ancho de la tabla (50% para cada una de las dos columnas). Fijaos en la función proportional-column-width. La versión 0.20.4 de FOP tampoco soporta el uso de porcentajes para el ancho (sí se pueden usar cm o pt), pero podemos saltar esta limitación con esta cómoda función (ojo, fijáos que se le pasa sólo un número; sin el símbolo «%»).