¿Cómo defino el ancho de columnas en una tabla de gpdf?
Pasa template.ColumnWidths(...) a c.Table. Los valores son porcentajes del ancho de la Col padre. Suman 100 para cubrir todo; los valores finales que falten se reparten automáticamente.
La pregunta, dicho de otra forma
Tengo una tabla con cuatro columnas. Por defecto, c.Table(header, rows) las hace todas del mismo ancho, pero para una factura la columna Descripción debería ser ancha y Cantidad debería ser estrecha. ¿Cómo le digo a gpdf el ancho por columna y qué unidad estoy fijando exactamente?
La respuesta rápida
Pasa template.ColumnWidths(...) como TableOption:
c.Table(header, rows, template.ColumnWidths(40, 15, 20, 25))
Los valores son porcentajes del ancho de contenido de la columna padre, no puntos. No tienen que sumar 100, pero normalmente deberían — lo que falte deja espacio en blanco a la derecha, lo que sobre se desborda de la celda.
Ese es el caso común. Lo interesante está en qué pasa cuando los porcentajes no suman 100, cuando pasas menos valores que columnas, y qué es realmente el "ancho padre".
Código que funciona (tabla de factura de cuatro columnas)
package main
import (
"log"
"os"
"github.com/gpdf-dev/gpdf"
"github.com/gpdf-dev/gpdf/document"
"github.com/gpdf-dev/gpdf/pdf"
"github.com/gpdf-dev/gpdf/template"
)
func main() {
doc := gpdf.NewDocument(
gpdf.WithPageSize(gpdf.A4),
gpdf.WithMargins(document.UniformEdges(document.Mm(20))),
)
header := []string{"Descripción", "Cant.", "Precio unit.", "Total"}
rows := [][]string{
{"Contrato anual de soporte", "1", "1.200,00 €", "1.200,00 €"},
{"Formación in situ (por día)", "3", "800,00 €", "2.400,00 €"},
{"Desarrollo de plantilla a medida", "12", "95,00 €", "1.140,00 €"},
}
page := doc.AddPage()
page.AutoRow(func(r *template.RowBuilder) {
r.Col(12, func(c *template.ColBuilder) {
c.Table(header, rows,
template.ColumnWidths(40, 15, 20, 25),
template.TableHeaderStyle(template.BgColor(pdf.Gray(0.92))),
)
})
})
data, err := doc.Generate()
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("invoice.pdf", data, 0o644); err != nil {
log.Fatal(err)
}
}
r.Col(12, ...) ocupa todo el ancho de la fila. La tabla vive dentro de esa columna, así que el 100% de la tabla = 100% del área de contenido de la grid Col. Con ColumnWidths(40, 15, 20, 25) sumando 100, cada punto PDF horizontal queda usado.
¿De qué son los porcentajes un porcentaje?
El número que pasas se envuelve en document.Pct(w) y se resuelve contra el ancho de contenido de la tabla. Eso es el ancho de la grid Col en la que vive la tabla, menos el margen, padding y borde de la tabla (en la práctica, el ancho de la Col tal cual — el estilo de la tabla viene sin decoración por defecto).
Así que con r.Col(6, ...) (la mitad de la fila) y ColumnWidths(50, 50), cada columna de la tabla es el 25% del ancho de la fila, no el 50%. Los porcentajes son locales a la tabla, no relativos a la página.
Esto importa cuando cambias una tabla de fila completa a una disposición lado a lado. La llamada a ColumnWidths no necesita cambiar — escala sola.
Qué hace gpdf cuando las cuentas no cuadran
Aparecen dos casos constantemente. La capa de layout los maneja de forma específica que vale la pena conocer.
Caso 1: los porcentajes no suman 100. Cada valor se toma tal cual. ColumnWidths(40, 30, 20) en una tabla de tres columnas produce columnas al 40%, 30% y 20% del padre — dejando el 10% libre a la derecha. ColumnWidths(50, 50, 50) se desborda; la tercera columna se sale del borde del padre y puede invadir la columna adyacente o salirse de la página.
No hay paso de normalización. gpdf confía en que tú hagas la aritmética.
Caso 2: menos anchos que columnas. Este es el más interesante. Las columnas finales se vuelven auto-width y reparten el resto por igual:
// Tabla de tres columnas, solo dos anchos.
c.Table(header3, rows3, template.ColumnWidths(40, 30))
// → 40% / 30% / 30% (la tercera columna recibe 100 - 40 - 30 = 30%)
Si los anchos explícitos ya suman 100 o más, las columnas auto se quedan con ancho cero y desaparecen de hecho. Si suman menos de 100, lo que sobra se divide a partes iguales entre las columnas auto:
// Tabla de cinco columnas, dos anchos dados.
c.Table(header5, rows5, template.ColumnWidths(50, 10))
// → 50% / 10% / 13,33% / 13,33% / 13,33% (40% repartido entre tres)
Hay un truco útil escondido en esta regla: pasar 0 también convierte una columna en auto. Así, ColumnWidths(0, 30, 30) en una tabla de tres columnas fija las dos últimas en 30% cada una y entrega el 40% restante a la primera columna. Es la forma de decir "me importan estos anchos concretos; el resto que lo decida gpdf".
La dirección contraria: demasiados anchos
Los valores extra más allá del número de columnas se ignoran en silencio. ColumnWidths(40, 30, 20, 10) en una tabla de dos columnas usa solo los dos primeros. Es indulgente pero también un imán para bugs — si borras una columna de la cabecera pero olvidas quitar el ancho correspondiente, gpdf no avisa. No hay log de advertencia.
El número de columnas en sí se deriva de la longitud de la fila de cabecera (o de la primera fila de body, si no hay cabecera). Añade una celda de cabecera y has añadido una columna; gpdf se dará cuenta y reequilibrará el ColumnWidths que pasaste.
Cuando los porcentajes no son lo que quieres
La API del builder solo expone porcentajes. Si realmente necesitas una columna de ancho fijo — por ejemplo, una columna "Cant." de 50 pt que no escale con la página — tienes que bajar una capa al árbol del documento:
import "github.com/gpdf-dev/gpdf/document"
tbl := &document.Table{
Columns: []document.TableColumn{
{Width: document.Auto},
{Width: document.Pt(50)},
{Width: document.Pt(80)},
{Width: document.Pt(80)},
},
Header: /* ... */,
Body: /* ... */,
}
Mezcla y combina: Auto, Pt, Mm, Pct funcionan en la capa document. La primera columna con Auto recoge lo que sobre tras restar las tres columnas fijas. Esto se parece más al elemento <col> de CSS que a un sistema de porcentajes.
Renuncias a la comodidad de que c.Table(header, rows, ...) te construya las celdas, pero para facturas que se imprimen sobre papel timbrado físico con posiciones de columna estables, el cambio merece la pena.
Recetas relacionadas
- ¿Cómo funciona la cuadrícula de 12 columnas en gpdf? — cómo las 12 columnas de la fila se convierten en el ancho padre contra el que se resuelven los porcentajes de la tabla
- Generar un PDF de factura en Go en menos de 50 líneas —
ColumnWidths(40, 15, 20, 25)en el contexto del resto de un documento de factura
Prueba gpdf
gpdf es una biblioteca Go para generar PDFs. Licencia MIT, cero dependencias externas, soporte CJK nativo.
go get github.com/gpdf-dev/gpdf