Llegan las Tablas a PDFDocument

Desde Xojo 2022r3 es posible crear y añadir tablas a los documentos PDF realizados con Xojo en proyectos Desktop y Web mediante la clase PDFTable.

Entre otras cosas, no tendrás que encargarte de realizar ningún tipo de cálculo sobre la posición o tamaño de las filas de la tabla, o si es el momento de añadir una nueva página.

Puedes descargar el proyecto de ejemplo desde este enlace.

Estas son las principales capacidades de las Tablas en PDFDocument:

  • Compatibles con proyectos Desktop, Web, Consola y Raspberry Pi.
  • Filas de altura variable.
  • Capacidad de añadir automáticamente las cabeceras de la tabla al inicio de cada nueva página.
  • Saltos de página —añadir nuevas páginas— automáticamente al documento.

Para ello, la clase PDFTable trabaja en combinación con la interfaz de clase PDFTableDataSource. Dicha interfaz de clase es la encargada de definir los métodos invocados al añadir una instancia de PDFTable en el documento PDF.

PDFTableDataSource

Al tratarse de una interfaz de clase significa que cualquier ventana/página web o bien las clases que creemos pueden actuar como fuente de datos para las tablas añadidas al documento PDF. Por ejemplo, podríamos crear nuestra propia subclase para trabajar con una base de datos y añadir a dicha subclase la interfaz de clase PDFTableDataSource; o bien simplemente añadir dicha interfaz de clase sobre cualquier ventana/página web de nuestro proyecto.

La interfaz de clase PDFTableDataSource define los siguientes métodos:

  • AddNewRow(rowCount As Integer) As Boolean. El parámetro rowCount contiene el número de filas se han añadido a la tabla. Si se devuelve el valor booleano True se añadirá una nueva fila; si se devuelve False se finalizará el dibujado de la tabla.
  • HeaderHeight As Double. En la implementación de este método indicaremos la altura deseada para la Cabecera de la tabla.
  • PaintCell(g As Graphics, row As Integer, column As Integer). Este es el método invocado para que podamos dibujar sobre la celda de la tabla indicadas por los parámetros row (fila) y column (columna). Como puedes observar este método recibe su propio contexto gráfico, indicado por el parámetro ‘g’. Así se dispone de toda la flexibilidad sobre la representación gráfica de los contenidos a incluir.
  • PaintHeaderContent(g As Graphics, column As Integer). En la implementación de dicho método podremos decidir cómo queremos dibujar sobre el contexto gráfico recibido (indicado por el parámetro ‘g’) la Cabecera correspondiente al número de Columna recibida en el parámetro ‘column’.
  • RowHeight As Double. Por último, en la implementación de este método devolveremos el valor de altura deseado para la nueva fila añadida a la tabla.

PDFTable

Se trata de una clase realmente simple que expone las siguientes propiedades:

  • ColumnCount As Integer. En esta propiedad se indica el número de columnas que tendrá la tabla.
  • ColumnWidths As String. Indicaremos, separados por comas, los valores de ancho para cada una de las columnas de la tabla.
  • DataSource As PDFTableDataSource. En dicha propiedad se asignará el objeto que actuará como fuente de datos para la tabla.
  • HasRepeatingHeader As Boolean. Indicaremos en dicha propiedad si deseamos repetir la cabecera de la tabla en el inicio de cada nueva página.

Por ejemplo, el siguiente fragmento de código creará una tabla compuesta por un total de tres columnas de igual ancho y en el que se repetirá la cabecera al inicio de cada nueva página añadida al documento PDF.

El objeto que actuará como fuente de datos será el mismo en el que se ha añadido el fragmento de código; de ahí que la asignación sea ‘Self’:

Var d As New PDFDocument

Var tTable As New PDFTable
tTable.ColumnCount = 3
tTable.ColumnWidths = "150,150,150"
tTable.DataSource = Self
tTable.HasRepeatingHeader = True

La forma en la que se añade una instancia de PDFTable a la página en curso del documento PDF es mediante el método AddTable(table As PDFTable, x As Double, y As Double) de PDFDocument; por ejemplo:

Var x As Double = d.PageWidth/2 - 450/2

d.addTable(tTable,x,20)

PDFTable en la práctica

A continuación veremos a través de un ejemplo simple cómo crear un documento PDF en el que se añade una tabla (centrada horizontalmente sobre la página), compuesta por un total de tres columnas de igual ancho, filas de tamaño variable (altura aleatoria), y en el que se da la opción al usuario de repetir la cabecera al inicio de cada nueva página.

El contenido propiamente dicho de las celdas también será aleatorio, pudiendo variar entre el rellenado de un color aleatorio, texto indicando el número de fial y columna en la que se encuentra la celda, la inclusión de una imagen añadida al proyecto o bien dejar la celda en blanco.

Empezaremos creando un nuevo proyecto Desktop. Con la ventana Window1 seleccionada en el Navegador pulsaremos el botón “Choose…” del Panel Inspector correspondiente al campo Interfaces. Esta acción abrirá una ventana con todas las Interfaces de Clase disponibles.

Ubica en el listado la Interfaz de Clase PDFTableDataSource, selecciona la casilla de verificación asociada y, al confirmar la selección, verás cómo se han añadido sobre Window1 los métodos declarados por la interfaz de clase.

Añade ahora una casilla de verificación arrastrándola desde la Librería sobre la esquina superior izquierda de la ventana en el Editor de diseño y ajusta el siguiente campo en el Panel Inspector asociado con el control:

  • Name: RepeatHeaderCB
  • Visual State: Checked

A continuación, arrastra un botón desde la Librería y sitúalo sobre la esquina superior derecha de Window1 en el Editor de Diseño. Con el botón Button1 aún seleccionado en el Navegador, elige la opción Add to “Button1” > Event Handler… desde el menú contextual. En la ventana resultante, selecciona el evento Pressed y confirma la selección.

Con el evento Pressed seleccionado en el Navegador, añade el siguiente fragmento en el Editor de Código asociado:

Var d As New PDFDocument

Var tTable As New PDFTable
tTable.ColumnCount = 3
tTable.ColumnWidths = "150,150,150"
tTable.DataSource = Self
tTable.HasRepeatingHeader = RepeatHeaderCB.Value

Var x As Double = d.PageWidth/2 - 450/2

d.addTable(tTable,x,20)

d.Save(SpecialFolder.Desktop.Child("Table.pdf"))

Arrastra cualquier imagen que quieras utilizar en tu ejemplo sobre el Navegador del IDE, de modo que quede importada al proyecto. En nuestro ejemplo utilizamos una imagen con el nombre “XojoLogo100”. Cuando añadas tu imagen, puedes asignarle el mismo nombre o bien modificar todas las partes del código en el que se haga referencia al nombre de imagen utilizada en este ejemplo.

Ahora ya sólo nos queda escribir el código correspondiente a la implementación de cada uno de los cinco métodos añadidos por la Interfaz de Clase PDFTableDataSource.

En el método AddNewRow:

Return rowCount < 100 // Nuestra tabla contará con un total de 100 filas.

En el método HeaderHeight:

Return 30 // Esta será la altura correspondiente a las celdas de la cabecera de la tabla.

En el método PaintCell:

Var rd As New Random

Var option As Integer = rd.InRange(1,4)

Select Case option

Case 1

  Var s As String = "row: " + row.ToString + " column: " + Column.ToString
  Var h As Double = g.Height/2 + g.TextHeight/2
  g.DrawText s,5,h

Case 2

  g.DrawPicture(XojoLogo100,0,0)

Case 3

  g.DrawingColor = Color.RGB(rd.InRange(0,255), rd.InRange(0,255), rd.InRange(0,55))
  g.FillRectangle(2,2,g.Width-4,g.Height-4)

Case 4

 // Empty cell
End Select

g.DrawingColor = Color.Black
g.DrawRectangle 0,0, g.Width,g.Height

Y este es el código que utilizaremos para dibujar el contenido de las celdas de la cabecera en el método PaintHeaderContent:

Var tRandom As New Random

Var c As Color

Select Case Column
Case 0
  c = color.Red
Case 1
  c = Color.Green
Case 2
  c = Color.Blue
End Select

g.DrawingColor = c
g.FillRectangle 0,0,g.Width,g.Height

Var s As String = "Column: " + Column.ToString

Var x, y As Double
x = (g.Width/2) - (g.TextWidth(s)/2)
y = (g.Height/2) + (g.TextHeight/2)

g.DrawingColor = color.Black
g.DrawText s, x, y

Por último, el código responsable de indicar la altura de cada nueva fila añadida a la tabla en el método RowHeight. Como puedes ver, se calculará de forma aleatoria entre un mínimo de 25 y un máximo de 100 puntos:

Var rd As New Random

return rd.InRange(25,100)

El resultado

Ya está todo lo necesario para crear nuestro primer PDF con una tabla de ejemplo. Ejecuta la aplicación, pulsa el botón y verás cómo se crea un nuevo documento PDF en el escritorio de tu equipo con el nombre de archivo “Table.pdf”. La cantidad de páginas del archivo PDF resultante puede variar dado a que la altura de las filas se calcula de forma aleatoria.

Prueba a continuación a repetir la operación pero, en esta ocasión, quita la marca en la casilla de verificación. Cuando pulses el botón para generar el documento PDF nuevamente comprobarás como en esta ocasión no se repite la cabecera en cada una de las páginas añadidas.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *