Todas as publicações

Como faço linhas com listras (zebra) em uma tabela?

Passe template.TableStripe na chamada Table. O gpdf pinta as linhas alternadas do corpo com a cor que você fornecer. Sem laço de linhas, sem estilizar célula a célula.

A pergunta, em outras palavras

Tenho uma tabela — notas fiscais, lançamentos, linhas de log, qualquer coisa com mais de 5 linhas — e quero que cada outra linha receba um cinza para o olho seguir a linha sem se perder. O Bootstrap chama isso de .table-striped. Quero o mesmo, no gpdf, sem escrever um laço de linhas.

Resposta curta

c.Table(header, rows, template.TableStripe(pdf.RGBHex(0xF5F5F5)))

É só isso. O gpdf cuida da alternância. O cabeçalho fica de fora; só as linhas do corpo recebem listra. A primeira linha do corpo permanece limpa, a segunda recebe tom, a terceira limpa, a quarta com tom, e assim por diante.

Código que funciona

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))),
    )

    brand := pdf.RGBHex(0x1A237E)     // fundo do cabeçalho
    stripe := pdf.RGBHex(0xF5F5F5)    // tom em linha alternada

    page := doc.AddPage()
    page.AutoRow(func(r *template.RowBuilder) {
        r.Col(12, func(c *template.ColBuilder) {
            c.Text("Vendas T1", template.FontSize(20), template.Bold())
            c.Spacer(document.Mm(4))

            c.Table(
                []string{"Produto", "Região", "Qtd.", "Receita"},
                [][]string{
                    {"Laptop Pro 15",  "AN",   "120", "R$ 778.800"},
                    {"Wireless Mouse", "EU",   "640", "R$ 95.965"},
                    {"USB-C Hub",      "APAC", "410", "R$ 102.475"},
                    {"Monitor 27\"",   "AN",   "180", "R$ 359.100"},
                    {"Keyboard",       "EU",   "320", "R$ 127.980"},
                    {"Webcam HD",      "APAC", "260", "R$ 116.985"},
                },
                template.ColumnWidths(40, 20, 15, 25),
                template.TableHeaderStyle(
                    template.TextColor(pdf.White),
                    template.BgColor(brand),
                ),
                template.TableStripe(stripe),
            )
        })
    })

    data, err := doc.Generate()
    if err != nil {
        log.Fatal(err)
    }
    if err := os.WriteFile("vendas.pdf", data, 0o644); err != nil {
        log.Fatal(err)
    }
}

go run main.go. Seis linhas no corpo, três tingidas, cabeçalho em azul-marinho com texto branco. O tipo de relatório que vai por e-mail na segunda-feira de manhã.

Como a alternância acontece

Internamente, o gpdf percorre as linhas do corpo com um índice i começando em 0 e aplica a listra nas linhas em que i%2 == 1. O cabeçalho fica em outro slice e não entra na contagem.

Índice da linha (base 0)Posição visualListrada?
0não
1sim
2não
3sim
.........

Essa paridade casa com a convenção do Bootstrap. A primeira linha de dados fica limpa e a listra atua como uma "pausa" visual — o olho atravessa a linha branca, a próxima está sombreada, repete.

Não há opção para inverter a paridade (listrar as linhas de índice par). Se você realmente quiser, basta inserir uma linha vazia no início do corpo — mas ninguém realmente quer esse efeito.

Escolher a cor

O ponto é ser discreto. Uma listra forte o suficiente para competir com o texto se anula sozinha.

pdf.RGBHex(0xF5F5F5) // cinza quente suave — território do padrão Bootstrap
pdf.RGBHex(0xFAFAFA) // ainda mais suave, quase imperceptível em tamanhos pequenos
pdf.RGBHex(0xEEF2FF) // tom pálido de marca (funciona se o cabeçalho for cor de marca)
pdf.Gray(0.96)       // equivalente em escala de cinza — economiza alguns bytes em PDF/A

Evite cores saturadas. Uma listra azul a 60 % de saturação é lida como "esta linha está selecionada / importante" e quebra o varrimento horizontal que o efeito zebra deveria resolver.

Para temas escuros (raro em PDF, mas existem em relatórios tipo apresentação), pdf.RGBHex(0x202020) sobre uma página 0x1A1A1A funciona. Mantenha a diferença de contraste baixa.

Combine com bordas de célula

Listras sozinhas bastam para tabelas curtas. Para tabelas densas, estilo financeiro, combine as listras com WithTableCellBorder para desenhar um filete entre cada célula:

hairline := template.Border(
    template.BorderWidth(document.Pt(0.5)),
    template.BorderColor(pdf.Gray(0.85)),
)

c.Table(header, rows,
    template.ColumnWidths(40, 20, 15, 25),
    template.TableHeaderStyle(
        template.TextColor(pdf.White),
        template.BgColor(brand),
    ),
    template.TableStripe(pdf.RGBHex(0xF5F5F5)),
    template.WithTableCellBorder(hairline),
)

Bordas finas + listra clara = aquele aspecto de pré-visualização de impressão de planilha contábil, de propósito. Mantenha a borda mais clara que a listra, para a listra continuar sendo o sinal dominante.

Se você só quer uma moldura externa (sem grade interna), troque WithTableCellBorder por WithTableBorder.

Erros que custam dez minutos

  • Cor no intervalo errado. pdf.RGB(245, 245, 245) produz uma caixa preta. O construtor espera 0.0–1.0, não 0–255. Use pdf.RGBHex(0xF5F5F5) se você pensa em valores no padrão CSS.
  • Listrar o cabeçalho. TableStripe não toca o cabeçalho. Se quiser cabeçalho com tom, é TableHeaderStyle(template.BgColor(...)) — outra opção. Confundir as duas e depois se perguntar por que o cabeçalho não fica tingido é o erro clássico de primeira vez.
  • Alternância em duas cores. O gpdf aceita uma única cor de listra, não duas. Imaginar um ciclo [branco, cinza, azul] não é recurso da lib — e seria hostil ao leitor.
  • Listrar uma tabela de 3 linhas. A listra precisa de pelo menos 4–5 linhas no corpo para fazer o trabalho. Com 2–3 linhas, parece que uma célula foi selecionada por engano. Pule; deixe a tabela respirar.

Receitas relacionadas

Experimente o gpdf

O gpdf é uma biblioteca Go para gerar PDFs. Licença MIT, zero dependências externas, processamento TrueType em Go puro.

go get github.com/gpdf-dev/gpdf

⭐ Star no GitHub · Documentação