Cabeçalho e rodapé do PDF exportado
Toda listagem e relatório com Exportável ligado gera um PDF. O cabeçalho e o rodapé desse arquivo são montados num editor visual: logo, título, data, período filtrado, paginação — e agora a unidade, o usuário, a empresa e qualquer dado próprio do seu app, como o CNPJ.
O que você vai obter
Exemplo do PDF exportado, com dados fictícios. Cada etiqueta azul é um campo do editor; a laranja é um dado do seu app.
Unidade Recife{UNIT_NAME}
00.000.000/0001-00{CNPJ}
| Código | Descrição | Financiador | Valor total |
|---|---|---|---|
| AMB-001 | Ações de incidência | Doadores diversos | 120.000,00 |
| DOAC | Doações diversas | Doadores diversos | 48.500,00 |
| FUNDO RI | Fundo de reserva institucional | Doadores diversos | 310.000,00 |
O cabeçalho e o rodapé se repetem em todas as páginas do PDF. Nada disso aparece na tela do sistema — só no arquivo exportado. Planilha e CSV não têm cabeçalho.
Configurar para uma página ou para o projeto inteiro
Painel da página → seção Exportação PDF → Configurar cabeçalho e rodapé… — ou rail → Configurações do projeto → Exportação de PDF
Há dois lugares para montar as bandas, e eles se combinam. Cada banda (cabeçalho e rodapé, separadamente) usa a configuração mais específica que encontrar:
Na página, o botão Usar padrão do projeto descarta a configuração própria e volta a herdar. No projeto, Remover configuração volta ao visual automático.
O editor: uma folha em milímetros
Diálogo Cabeçalho e rodapé do PDF
O editor mostra uma folha A4 com as duas faixas, deitada ou em pé conforme a orientação. Você arrasta elementos da paleta da esquerda para a faixa, move com o mouse ou com as setas (0,5 mm; com Shift, 5 mm) e as guias rosa alinham para você. À direita, o elemento selecionado: posição, alinhamento na faixa, tipografia e cor.

Os elementos
- Texto — texto fixo: razão social, endereço, um aviso de confidencialidade. Também é aqui que entram os dados próprios do app.
- Logo / imagem — o logo do projeto (grande ou pequeno, definidos em Configurações do projeto) ou uma imagem sua, até 400 KB.
- Nº de página — "Página 1 de 3", "1/3" ou só o número.
- Data — data e hora da exportação.
- Campo dinâmico — qualquer chip da lista Campos disponíveis: título, período, filtros, unidade, usuário…
- Campos do projeto — os campos próprios definidos nas configurações do projeto (CNPJ, endereço). Chegam como texto e a prévia mostra o valor.
Modelos prontos
Para não começar do zero, Modelos prontos aplica um par cabeçalho + rodapé — Corporativo clássico, Timbrado completo, Relatório financeiro, Confidencial… Depois mova e troque o que quiser; nada é definitivo.

Altura, respiro e fundo
Cada faixa tem uma altura em milímetros e um respiro — o espaço entre a faixa e a tabela. Aumente a altura quando o logo ficar cortado. Fundo colorido pinta a faixa inteira: bom para um cabeçalho em faixa azul ou navy; combine com texto claro.
Orientação e linha do cabeçalho
Orientação, no topo do editor, escolhe entre Paisagem (o padrão) e Retrato. Retrato serve bem a relatórios com poucas colunas; numa listagem larga, as colunas que não cabem na largura da folha ficam cortadas. Na página, Padrão do projeto segue o que estiver nas configurações do projeto. Ao trocar a orientação, os elementos das faixas personalizadas são reposicionados na nova largura; confira o resultado na folha.
Com o cabeçalho padrão (sem layout personalizado), o painel da direita mostra Linha abaixo do cabeçalho: azul (padrão), cinza igual ao rodapé, sem linha ou outra cor. Exige Mad Framework 5.103.0 ou superior; republique o projeto para aplicar.
Campos disponíveis
Paleta → Campos disponíveis · ou o seletor Campo de um campo dinâmico já colocado
| Campo | O que imprime | Quando sai vazio |
|---|---|---|
{TITLE} | Título da exportação — o Título da exportação da grade ou, sem ele, o título da página. | Nunca. |
{SUBTITLE} | O Subtítulo da exportação da grade. | Grade sem subtítulo. |
{DATE} | Data e hora em que o PDF foi gerado. | Nunca. |
{PERIOD} | O período escolhido no filtro de data, já formatado ("de 01/03/2026 a 31/03/2026", "Março/2026"). | Tela sem filtro de período, ou a pessoa não escolheu datas. |
{FILTERS} | Os filtros ativos com rótulo ("Financiador: Fundação X · Situação: Ativo"). | Nenhum filtro preenchido. |
{TOTAL_REGISTER} | Quantidade de registros no PDF. | Nunca. |
{APP_NAME} | Nome do app publicado. | Nunca. |
{TENANT_NAME} 5.79 | Nome da empresa (tenant) da pessoa logada. | App sem tenancy. |
{UNIT_NAME} 5.79 | Nome da unidade (filial) ativa da pessoa logada. | App sem multi-unidade, ou pessoa sem unidade vinculada. |
{USER_NAME} 5.79 | Nome de quem exportou. | Nunca, com alguém logado. |
{LOGO} · {LOGO_SMALL} | Logo do projeto — pelo elemento Logo / imagem. | Projeto sem logo cadastrado: o espaço some. |
{PAGE_NUM} · {PAGE_COUNT} | Número da página e total — pelo elemento Nº de página. | Nunca. |
Os chips funcionam também dentro de um elemento de Texto: "Emitido por {USER_NAME} em {DATE}" vira uma frase só. Título, subtítulo e nome do arquivo da exportação ficam no painel da grade (seção Relatório) e aceitam {PERIOD}. Os campos do seu app — CNPJ, endereço — entram pelo grupo Campos do projeto; veja 05.
Quem emite: unidade, usuário e empresa
Chips Unidade, Usuário e Empresa em Campos disponíveis
Três campos identificam quem gerou o arquivo. Eles leem a sessão da pessoa logada no app publicado — não precisam de configuração na página:
- Unidade (
{UNIT_NAME}) — a filial ativa. Em app multi-unidade, é a unidade escolhida no login ou na troca de unidade; o PDF acompanha a troca. - Usuário (
{USER_NAME}) — o nome de quem clicou em exportar. Útil em rodapé de auditoria: "Emitido por … em …". - Empresa (
{TENANT_NAME}) — o cliente/tenant, em app com tenancy. Em app de uma empresa só, prefira o nome fixo em Texto.
Em app sem multi-unidade ou sem tenancy o campo sai em branco — nunca imprime o token cru. Se o seu app tem unidades e mesmo assim sai vazio, veja Problemas comuns.
Dados próprios do app no cabeçalho
Configurações do projeto → Exportação de PDF → Campos próprios · e, para valores calculados, o botão Criar classe de campos
CNPJ, inscrição estadual, endereço, nome fantasia, o responsável pelo setor — qualquer valor que o seu app conheça pode virar um campo do PDF. São três caminhos, do mais simples ao mais flexível; use o primeiro sempre que o valor não muda.
1. Valor fixo — sem código
- Em Configurações do projeto → Exportação de PDF, abaixo da prévia, está Campos próprios. Digite o nome (
CNPJ) e o valor (12.345.678/0001-90) e clique em Adicionar. O nome vira automaticamente{CNPJ}. - Salve as configurações. No editor de cabeçalho e rodapé — de qualquer página ou do projeto — o campo aparece na paleta em Campos do projeto. Arraste como qualquer outro; a prévia já mostra o valor.
2. Valor calculado, para todas as telas — a classe de campos
Usuário logado, data por extenso, um dado que vem do banco: isso muda a cada exportação, então precisa de código. Na mesma seção, Criar classe de campos cria o arquivo PdfExportPlaceholders (um Helper do app, em app/Helpers) já com exemplos comentados e abre no editor. Depois o botão vira Abrir classe de campos. Cada chave do array é um campo:
final class PdfExportPlaceholders
{
public static function resolve(): array
{
return [
'RESPONSAVEL' => (string) session('username'),
'EMITIDO_EM' => now()->format('d/m/Y H:i'),
];
}
}
No editor, esses campos entram como Texto com o nome entre chaves — {RESPONSAVEL}. A prévia mostra o token como está (o editor não sabe o valor); o PDF sai preenchido.
3. Valor de uma tela só — o que a pessoa filtrou, quem está logado
No PHP da página (aba Código, fora dos blocos @mad-block), o método exportPdfPlaceholders() devolve os campos daquela tela. Ele roda no momento da exportação, então enxerga exatamente o que a pessoa escolheu no formulário de busca e quem está logado. Exemplo de um relatório de convênios com os filtros Contrato, Financiador e um período:
protected function exportPdfPlaceholders(): array
{
// Cada campo do formulário de busca é uma propriedade pública da página,
// com o mesmo `name` do Blade: name="contrato" → $this->contrato.
// Combo guarda o id da opção escolhida — pra imprimir o nome, busque no model.
$financiador = $this->idfinanciador !== ''
? \App\Models\Financiador::find($this->idfinanciador)?->nome
: null;
return [
'CONTRATO' => $this->contrato ?: 'todos', // campo de texto da busca
'FINANCIADOR' => $financiador ?? 'Todos', // combo → nome
'PERIODO' => $this->reportPeriodLabel() ?: 'todo o período', // mesmo texto do {PERIOD}
'EMAIL' => (string) session('usermail'), // sessão de quem exporta
'PERFIL' => (string) session('login'),
];
}
No editor, esses campos entram como Texto: "Contrato {CONTRATO} · Financiador {FINANCIADOR}" no cabeçalho, "Emitido por {EMAIL}" no rodapé.
- Formulário de busca — cada
name="…"do<mad-grid-filters>vira$this->nome; campo vazio é''. Data de período:$this->dtIni/$this->dtFim(ou mês/ano:$this->mes/$this->ano);reportPeriodLabel()já devolve o texto formatado.$this->currentFilters()traz os filtros preenchidos de uma vez, como['contrato' => '…']— junto vêm outras propriedades públicas da grade (sortDir,exportColConfigs), então leia só as chaves que interessam. - Sessão —
session('username')(nome),session('usermail'),session('login'),session('userunitname')(unidade),session('userunitid'). Nome, unidade e empresa já existem como chips ({USER_NAME},{UNIT_NAME},{TENANT_NAME}); use a sessão para o que os chips não cobrem. - A chave pode vir com ou sem chaves (
'CNPJ'ou'{CNPJ}'). O valor é sempre texto puro. Uma chave que a classe global ou os campos fixos também definem é substituída só nesta tela — as outras continuam valendo.
protected preenchida no show() chega vazia aqui — recalcule dentro do método.{APP_NAME}, {DATE}, {UNIT_NAME}…): útil para imprimir a razão social no lugar do nome do app. Logo e paginação não podem ser substituídos.Publicar e testar
Barra de ações → Salvar → Teste Online ou publicar
- Salve a página (ou as configurações do projeto). O editor grava junto com a tela; não há botão "Salvar" dentro do diálogo.
- Abra o app no Teste Online ou publique. A configuração do projeto e a página vão juntas.
- Na listagem, clique em Exportar → PDF. Confira o cabeçalho na primeira e na última página — a paginação e o total só aparecem certos no arquivo, não na pré-visualização.
- Se usou unidade ou empresa, entre com um usuário vinculado a uma unidade e, em app multi-unidade, troque de unidade e exporte de novo.
{CNPJ} literal: atualize o framework pelo card Mad Framework da Central de Comando e republique.Referência
| Onde | O que | Efeito |
|---|---|---|
| painel da páginaExportação PDF | Padrão do projeto · Personalizado · Sem cabeçalho / Sem rodapé | Por banda. Personalizado abre o editor; Sem… tira a faixa e devolve o espaço à tabela. |
| configuraçõesExportação de PDF | Padrão do projeto | Herdado por toda página em Padrão do projeto. Gera o arquivo app/config/pdf-export.json no app. |
| editorOrientação | Padrão do projeto · Paisagem · Retrato | Papel do PDF. Sem configuração, paisagem. Framework 5.103. |
| editorLinha abaixo do cabeçalho | Azul · Cinza · Sem linha · Outra cor | Só no cabeçalho padrão. Framework 5.103. |
| editorAltura · respiro | mm | Altura da faixa e espaço até a tabela. A margem da página é a soma dos dois. |
| editorCampos disponíveis | chips | Ver 03. Os três de contexto exigem framework 5.79. |
| gradeTítulo · Subtítulo · Nome do arquivo da exportação | texto, aceita {PERIOD} | Alimentam {TITLE}, {SUBTITLE} e o nome do PDF. |
| configuraçõesCampos próprios | nome → valor fixo | Sem código. Vira chip Campos do projeto no editor e chega ao app pelo app/config/pdf-export.json. |
appApp\Helpers\PdfExportPlaceholders::resolve() | array chave → texto | Valores calculados para todo o projeto. O botão Criar classe de campos gera o arquivo; um erro nela não derruba a exportação. |
PHP da páginaexportPdfPlaceholders() | array chave → texto | Campos de uma tela só. Vence a classe, que vence os campos fixos; todos vencem os campos de texto do editor. |
protegidos{LOGO} · {LOGO_SMALL} · {PAGE_NUM} · {PAGE_COUNT} | — | Não podem ser sobrescritos pelo app: são o logo e a paginação. |
| documentosPágina do tipo Documento | — | Tem cabeçalho e rodapé próprios, montados no editor de documento — este guia não se aplica. |
Problemas comuns
O PDF saiu sem o meu cabeçalho
A página está em Padrão do projeto e o projeto não tem configuração — ou o app não foi republicado depois de salvar. Confira o status na seção Exportação PDF do painel e republique.
Configurei no projeto, mas uma página ignora
Essa página tem cabeçalho Personalizado. Abra o painel dela e use Usar padrão do projeto.
Unidade ou empresa sai em branco
Três causas, nesta ordem: o app roda um framework anterior ao 5.79; o app não tem multi-unidade/tenancy; a pessoa logada não está vinculada a uma unidade. Atualize o framework, confira as configurações de tenancy do projeto e o vínculo da pessoa em Unidades.
O meu {CNPJ} apareceu literal
Ninguém definiu esse campo: nem em Campos próprios das configurações, nem na classe de campos, nem na página. Confira o nome — precisa ser idêntico ao do editor, sem espaços — e se o app foi republicado com o framework 5.80 ou mais novo.
Adicionei um campo próprio e ele não aparece na paleta da página
Salve as configurações do projeto e reabra o editor de cabeçalho e rodapé da página: a lista de campos do projeto é carregada ao abrir.
Período e filtros saem em branco
O {PERIOD} só imprime com um filtro de data preenchido; o {FILTERS} exige que o app tenha sido republicado depois que a tela ganhou filtros.
O logo ficou cortado
Aumente a altura da faixa no editor, ou reduza a altura do elemento de imagem nas propriedades.
Em retrato, colunas saíram cortadas
A folha em pé tem 194 mm úteis, contra 281 mm deitada. Esconda colunas da exportação ou volte para Paisagem.
Escolhi retrato e o cabeçalho do projeto ficou cortado
O cabeçalho personalizado do projeto foi desenhado deitado. No editor da página, use Adaptar para esta página: ele copia o cabeçalho do projeto para a página já reposicionado para retrato.
O total de páginas aparece como 0 na prévia
É só na pré-visualização. No arquivo o número é calculado depois de paginar.