MAD Lab
/
Tutor > Documentos PDF > Tabelas em PDF

Tabelas em PDF

Documentos PDF

mad-doc-data-table mad-doc-data-table-column mad-doc-repeater
Tabela de dados

mad-doc-data-table + mad-doc-data-table-column lendo TutorDemoPedido, agrupado por categoria.

Pedidos recentes por categoria
Cód. Cliente Data Valor
▸ Brinquedos
128 Rafael Pereira 28/09/2026 6.685,43
55 Ana Souza 11/09/2026 4.464,35
11.149,78
▸ Eletrônicos
99 Rafael Pereira 24/09/2026 5.963,62
84 Gabriela Pereira 18/09/2026 7.745,58
141 Hugo Almeida 09/09/2026 5.400,52
64 Nelson Araújo 06/09/2026 846,66
19.956,38
▸ Vestuário
18 Fábio Souza 16/09/2026 703,92
27 Mariana Almeida 06/09/2026 5.617,90
117 Isabela Araújo 03/09/2026 807,20
7.129,02
▸ Móveis
108 Nelson Araújo 14/09/2026 2.321,95
2.321,95
▸ Alimentos
63 Karina Souza 11/09/2026 7.133,89
36 Diego Araújo 02/09/2026 5.981,71
13.115,60
53.672,73
TOTAL GERAL: 53.672,73
resources/views/tutor/examples/pdf-tabelas/tabela-pedidos.blade.php
@php
    $totalsPedidos = $totalsPedidos ?? new \ArrayObject();
@endphp
<mad-doc-heading :level="2">Pedidos recentes por categoria</mad-doc-heading>
<mad-doc-data-table model="TutorDemoPedido"
    :filter="fn($q) => $q->orderByDesc('dt_pedido')->limit(12)"
    :totals="$totalsPedidos" group-by="categoria.nome"
    header-bg="#eef2ff" :zebra="true" :font-size="9">
    <mad-doc-data-table-column label="Cód." field="id" align="center" width="50px" />
    <mad-doc-data-table-column label="Cliente" field="cliente.nome" align="left" />
    <mad-doc-data-table-column label="Data" field="dt_pedido" align="center" formatter="date" width="80px" />
    <mad-doc-data-table-column label="Valor" field="valor_total" align="right" formatter="money"
        total="sum" total-name="valor_geral" width="100px" />
</mad-doc-data-table>
<mad-doc-variable-field :value="$totalsPedidos['valor_geral'] ?? 'R$ 0,00'"
    prefix="TOTAL GERAL: " align="right" :size="12" :bold="true" />
Repetidor (layout livre)

mad-doc-repeater percorre os itens de um pedido com agregados (:aggregates).

Itens do pedido "Pedido #144"
Item avulso 8x R$ 4.240,64
Item avulso 6x R$ 4.293,54
Unidade padrão 6x R$ 3.784,62
Combo promocional 6x R$ 2.283,18
Total: 14.601,98 (26 un.)
resources/views/tutor/examples/pdf-tabelas/repeater-itens.blade.php
@php
    // Dois chamadores possíveis:
    //  - preview ao vivo (<x-tutor-demo>, escopo isolado): $pedidoDemo não
    //    existe ainda — busca no host via MadRenderContext (método público,
    //    NUNCA @php com query Eloquent direto no blade).
    //  - geração do PDF (TutorPdfTabelas::gerarPdf, chamado no mount() —
    //    ANTES de MadComponent::render() empurrar o contexto): o controller
    //    já passa $pedidoDemo pronto pro MadBlade::render().
    $pedidoDemo = $pedidoDemo ?? \Mad\Component\MadRenderContext::getComponent()?->pedidoDemo();

    $tutorRepeaterEmpty = '<p style="text-align:center;color:#94a3b8;">Sem itens.</p>';
@endphp
<mad-doc-heading :level="2">Itens do pedido "{{ $pedidoDemo->descricao }}"</mad-doc-heading>
<mad-doc-repeater :rows="$pedidoDemo->itens"
    :aggregates="[
        'qtd_total'         => ['op' => 'sum', 'field' => 'qtd',   'format' => 'integer'],
        'valor_total_itens' => ['op' => 'sum', 'field' => 'total', 'format' => 'money'],
    ]"
    :empty="$tutorRepeaterEmpty">
    <table style="width:100%;border-collapse:collapse;margin:2pt 0;font-size:9pt;">
        <tr>
            <td style="width:60%;"><strong>{{ $record->descricao }}</strong></td>
            <td style="width:15%;text-align:right;">{{ (int) $record->qtd }}x</td>
            <td style="width:25%;text-align:right;">R$ {{ number_format((float) $record->total, 2, ',', '.') }}</td>
        </tr>
    </table>
</mad-doc-repeater>
<mad-doc-text align="right" :size="11">
    <strong>Total: {{ $totals['valor_total_itens'] ?? '' }} ({{ $totals['qtd_total'] ?? 0 }} un.)</strong>
</mad-doc-text>
Código-fonte completo da página
app/control/Tutor/TutorPdfTabelas.php
<?php

namespace App\Control\Tutor;

use App\Models\TutorDemo\TutorDemoPedido;
use App\Support\Tutor\TutorDemoSeed;
use App\Support\Tutor\TutorPage;
use Mad\Doc\MadDocPdf;
use Mad\Service\MadUploadStorage;
use Mad\View\MadBlade;

/**
 * TutorPdfTabelas — tabelas em PDF: mad-doc-data-table, mad-doc-data-table-column,
 * mad-doc-repeater.
 *
 * Ao contrário de pdf_basico, nenhuma tag desta página é incompatível com o
 * preview ao vivo (sem <mad-doc-page>, sem position:fixed) — os parciais
 * "ao vivo" são exatamente os mesmos incluídos no wrapper -doc.blade.php
 * usado pra gerar o PDF (ver TutorPdfBasico pro caso onde isso NÃO vale).
 */
class TutorPdfTabelas extends TutorPage
{
    protected string $catalogKey = 'pdf_tabelas';

    private const EXEMPLOS = ['tabela-pedidos', 'repeater-itens'];

    /** exemplo => URL assinada do PDF já gerado (mad.download). */
    public array $pdfUrls = [];

    public function mount(array $params = []): void
    {
        TutorDemoSeed::ensure();

        foreach (self::EXEMPLOS as $exemplo) {
            $this->pdfUrls[$exemplo] = $this->gerarPdf($exemplo);
        }
    }

    /** Pedido fixo (o de maior valor) usado pelo exemplo de repeater — dados reais da fixture. */
    public function pedidoDemo(): TutorDemoPedido
    {
        return TutorDemoPedido::query()
            ->with('itens')
            ->orderByDesc('valor_total')
            ->firstOrFail();
    }

    private function gerarPdf(string $exemplo): string
    {
        // O exemplo "repeater-itens" lê $pedidoDemo via MadRenderContext no
        // preview ao vivo (host = esta página, contexto empurrado por
        // MadComponent::render()) — mas aqui em mount() esse contexto ainda
        // não existe (render() só empurra DEPOIS do mount). Passamos o dado
        // direto pro MadBlade::render(); @include sem array herda o escopo
        // do pai, então $pedidoDemo chega intacto no parcial.
        $data = $exemplo === 'repeater-itens' ? ['pedidoDemo' => $this->pedidoDemo()] : [];

        $html = MadBlade::render('tutor.examples.pdf-tabelas.' . $exemplo . '-doc', $data);
        $pdf  = MadDocPdf::fromHtml($html);

        $path = 'tutor-pdf/pdf-tabelas/' . $exemplo . '.pdf';
        MadUploadStorage::putContent($path, $pdf);

        return mad_download_url($path);
    }
}
resources/views/tutor/pdf/tabelas.blade.php
<x-tutor-page page="pdf_tabelas">
    <x-tutor-demo demo="tutor.examples.pdf-tabelas.tabela-pedidos"
        title="Tabela de dados" desc="mad-doc-data-table + mad-doc-data-table-column lendo TutorDemoPedido, agrupado por categoria." />
    <div style="margin:8px 0 24px;">
        <mad-btn variant="primary" icon="file-text" :href="$pdfUrls['tabela-pedidos']"
            attrs='target="_blank" rel="noopener"'>Ver PDF</mad-btn>
    </div>

    <x-tutor-demo demo="tutor.examples.pdf-tabelas.repeater-itens"
        title="Repetidor (layout livre)" desc="mad-doc-repeater percorre os itens de um pedido com agregados (:aggregates)." />
    <div style="margin:8px 0 24px;">
        <mad-btn variant="primary" icon="file-text" :href="$pdfUrls['repeater-itens']"
            attrs='target="_blank" rel="noopener"'>Ver PDF</mad-btn>
    </div>
</x-tutor-page>