Skip to content

Bands

Um relatório é dividido em faixas horizontais chamadas bands. Cada band tem uma altura fixa e contém elementos posicionados por coordenadas x e y.

┌──────────────────────────────────────┐
│  Header Band (repete em toda página) │
├──────────────────────────────────────┤
│  Detail Band (uma por registro)      │
│  Detail Band (uma por registro)      │
│  Detail Band (uma por registro)      │
│  ...                                 │
├──────────────────────────────────────┤
│  Summary Band (uma vez, após dados)  │
├──────────────────────────────────────┤
│  Footer Band (repete em toda página) │
└──────────────────────────────────────┘

Tipos

Aparece no topo de cada página do PDF. Usado para títulos, logos e informações fixas.

json
{
  "type": "header",
  "id": "header_main",
  "height": 100,
  "elements": [ ... ]
}

Detail

Repete uma vez para cada registro do data source vinculado. É aqui que os dados tabulares são renderizados.

json
{
  "type": "detail",
  "id": "detail_items",
  "dataSourceId": "items",
  "height": 30,
  "elements": [ ... ]
}

O dataSourceId indica qual data source alimenta esta band. Cada registro gera uma instância da band no documento final.

Summary

Aparece uma vez após todos os registros de detalhe. Usado para totais e agregados.

json
{
  "type": "summary",
  "id": "summary_totals",
  "height": 50,
  "elements": [ ... ]
}

Aparece no rodapé de cada página. Usado para paginação e informações legais.

json
{
  "type": "footer",
  "id": "footer_page",
  "height": 30,
  "elements": [ ... ]
}

Propriedades comuns

PropriedadeTipoObrigatórioDescrição
typestringSim"header", "detail", "summary", "footer", "groupHeader" ou "groupFooter"
idstringSimIdentificador único
heightdoubleSimAltura em pontos
elementsarraySimLista de elementos posicionados
dataSourceIdstringdetail, groupHeaderData source que alimenta a band
groupBystringgroupHeader, groupFooterCampo do data source usado para agrupar registros
forcePageBreakBeforeboolNãoSe true, insere quebra de página antes desta band
visibilitystringNãoControla em quais páginas a band é renderizada (header/footer)
showOnPageintNãoRenderiza somente na página informada (1-based). Sobrepõe visibility
printWhenstringNãoExpressão booleana — band é ocultada quando avalia false ou 0

As bands header e footer aceitam o campo visibility para controlar em quais páginas são renderizadas. Isso é útil para criar cabeçalhos de capa, rodapés de assinatura ou layouts que diferem por página.

ValorComportamento
"allPages" (padrão)Renderizada em todas as páginas
"firstPageOnly"Somente na primeira página
"lastPageOnly"Somente na última página
"allButFirst"Em todas exceto a primeira
"allButLast"Em todas exceto a última
"oddPagesOnly"Somente páginas ímpares (1, 3, 5…)
"evenPagesOnly"Somente páginas pares (2, 4, 6…)
"none"Nunca renderizada (band oculta)
json
{
  "type": "header",
  "id": "header_capa",
  "height": 120,
  "visibility": "firstPageOnly",
  "elements": [ ... ]
}
json
{
  "type": "footer",
  "id": "footer_assinatura",
  "height": 60,
  "visibility": "lastPageOnly",
  "elements": [ ... ]
}

showOnPage

Renderiza a band somente em uma página específica (1-based). Quando definido, sobrepõe visibility:

json
{
  "type": "header",
  "id": "header_pagina3",
  "height": 40,
  "showOnPage": 3,
  "elements": [ ... ]
}

Renderização condicional (printWhen)

A propriedade printWhen aceita uma expressão booleana avaliada em tempo de renderização. A band é ocultada quando a expressão avalia false ou 0. Usa o mesmo ExpressionEvaluator dos field bindings.

json
{
  "type": "summary",
  "id": "summary_totais",
  "height": 50,
  "printWhen": "total > 0",
  "elements": [ ... ]
}

Outros exemplos:

json
"printWhen": "pageNumber == 1"
"printWhen": "itemCount > 10"
"printWhen": "status == 'ativo'"

CSV e Excel

Em exportações CSV/Excel (sem conceito de página), qualquer valor de visibility diferente de "none" inclui a band. printWhen é avaliado normalmente.

Posicionamento

Elementos dentro de uma band usam coordenadas relativas ao canto superior esquerdo da band:

Band (height: 40)
┌───────────────────────────────┐
│  ┌─────┐                     │  Elemento em x:10, y:5
│  │ Txt │                     │
│  └─────┘                     │
│                    ┌────┐    │  Elemento em x:300, y:15
│                    │ Fld│    │
│                    └────┘    │
└───────────────────────────────┘

A coordenada y é relativa ao topo da band, não da página.

Múltiplas bands do mesmo tipo

Um relatório pode ter mais de uma band de cada tipo. A ordem no array bands define a ordem de renderização:

json
{
  "bands": [
    { "type": "header", "id": "h1", "height": 80, "elements": [...] },
    { "type": "header", "id": "h2", "height": 40, "elements": [...] },
    { "type": "detail", "id": "d1", "dataSourceId": "items", "height": 30, "elements": [...] },
    { "type": "summary", "id": "s1", "height": 50, "elements": [...] },
    { "type": "footer", "id": "f1", "height": 25, "elements": [...] }
  ]
}

Quebra de página forçada

json
{
  "type": "summary",
  "id": "sum",
  "height": 60,
  "forcePageBreakBefore": true,
  "elements": [ ... ]
}

O summary acima sempre começa em uma nova página.

Group Bands (quebra de grupo)

Relatórios gerenciais frequentemente exigem agrupamento — por vendedor, por cliente, por período. O Sulfite suporta isso com dois tipos de band: groupHeader e groupFooter.

┌──────────────────────────────────────┐
│  Header Band                         │
├──────────────────────────────────────┤
│  ┌── GroupHeader (vendedor: "Ana") ──┐
│  │  Detail Band (venda 1)            │
│  │  Detail Band (venda 2)            │
│  └── GroupFooter (subtotal Ana) ─────┘
│  ┌── GroupHeader (vendedor: "Carlos")┐
│  │  Detail Band (venda 3)            │
│  └── GroupFooter (subtotal Carlos) ──┘
├──────────────────────────────────────┤
│  Summary Band (total geral)          │
├──────────────────────────────────────┤
│  Footer Band                         │
└──────────────────────────────────────┘

GroupHeader

Renderiza uma vez no início de cada grupo. O campo groupBy indica qual campo do data source define a quebra.

json
{
  "type": "groupHeader",
  "id": "gh_vendedor",
  "dataSourceId": "vendas",
  "groupBy": "vendedor",
  "height": 35,
  "elements": [
    { "type": "field", "id": "f_vendedor", "x": 10, "y": 8, "width": 300, "binding": "vendedor", "bold": true, "fontSize": 14 }
  ]
}

GroupFooter

Renderiza uma vez no final de cada grupo. Ideal para subtotais. O AggregateElement dentro de um groupFooter calcula o agregado apenas sobre os registros do grupo.

json
{
  "type": "groupFooter",
  "id": "gf_vendedor",
  "groupBy": "vendedor",
  "height": 30,
  "elements": [
    { "type": "aggregate", "id": "subtotal", "x": 300, "y": 5, "width": 100, "verb": "SUM", "dataSourceId": "vendas", "targetKey": "valor", "format": "currency:BRL", "bold": true }
  ]
}

Exemplo completo com agrupamento

json
{
  "bands": [
    { "type": "header", "id": "hdr", "height": 60, "elements": [...] },
    { "type": "groupHeader", "id": "gh", "dataSourceId": "vendas", "groupBy": "vendedor", "height": 35, "elements": [...] },
    { "type": "detail", "id": "det", "dataSourceId": "vendas", "height": 25, "elements": [...] },
    { "type": "groupFooter", "id": "gf", "groupBy": "vendedor", "height": 30, "elements": [...] },
    { "type": "summary", "id": "sum", "height": 40, "elements": [...] },
    { "type": "footer", "id": "ftr", "height": 30, "elements": [...] }
  ]
}

O DataProcessor agrupa os registros automaticamente pela chave groupBy e renderiza a hierarquia: groupHeader → detail rows → groupFooter para cada grupo.

printWhen em GroupHeader

Se o groupHeader tem printWhen que avalia false, o grupo inteiro (header + details + footer) é suprimido.

Exportação multiformato

GroupBands funcionam em todos os formatos: PDF, HTML, CSV e Excel. Cada renderer respeita a hierarquia de grupo e o printWhen.

Editando bands no Studio

O Sulfite Studio oferece dois pontos de edição de bands sem precisar editar JSON manualmente:

  • Painel lateral — expanda uma band no painel esquerdo do designer para editar height, dataSourceId, forcePageBreakBefore, visibility, showOnPage e printWhen diretamente.
  • BandManagerDialog — aberto pela toolbar (botão Gerenciar Bands), exibe todas as bands em cards expansíveis com todos os campos editáveis, drag & drop para reordenar e botão de exclusão com confirmação.

Todas as edições feitas no Studio são refletidas imediatamente no editor JSON (modo Code) e vice-versa.

Próximo passo

Data Sources →

Sulfite do 🇧🇷 para o mundo © 2026 Rafael S. Pinheiro