K

Tabulka

Exporty tabulky

Aktuální dotaz jako CSV, Excel nebo PDF — hledání, filtry, řazení i viditelné sloupce přesně tak, jak jsou vidět.

Na této stránce

Wire Table umí exportovat aktuální dotaz tabulky jako CSV, Excel nebo PDF. Exporty používají aktuální hledání, filtry, řazení a viditelné sloupce.

Základní tlačítka exportu

Přidejte tlačítka nebo položky menu, které volají exportTable() z Livewire komponenty používající WithTable.

<button type="button" wire:click="exportTable('csv')">
Export CSV
</button>
 
<button type="button" wire:click="exportTable('xlsx')">
Export Excel
</button>
 
<button type="button" wire:click="exportTable('pdf')">
Export PDF
</button>

Podporované hodnoty formátu:

Hodnota Typ souboru
csv CSV
xlsx Excel
pdf PDF

Konfigurace výchozích hodnot exportu

Použijte ExportAction v headerActions(), když chcete definovat konfiguraci exportu v definici tabulky.

use NyonCode\WireTable\Export\ExportAction;
use NyonCode\WireTable\Export\ExportFormat;
use NyonCode\WireTable\Export\TableExport;
 
public function table(Table $table): Table
{
return $table
->model(User::class)
->columns([
TextColumn::make('name')->label('Name')->searchable()->sortable(),
TextColumn::make('email')->label('Email')->searchable(),
TextColumn::make('role')->label('Role'),
])
->headerActions([
ExportAction::makeExport()
->formats([ExportFormat::Csv, ExportFormat::Excel])
->exportConfig(
TableExport::make()
->fileName('users')
->delimiter(';')
->withHeadings()
),
]);
}

Stahování stále probíhá přes exportTable('csv'), exportTable('xlsx') nebo exportTable('pdf'). První ExportAction na tabulce poskytuje výchozí nastavení exportu.

Exportované sloupce

Ve výchozím stavu exporty zahrnují sloupce tabulky viditelné aktuálnímu uživateli. Sloupce skryté uživatelem se přeskočí.

Pro export vlastní sady sloupců:

TableExport::make()
->columns([
TextColumn::make('name')->label('Name'),
TextColumn::make('email')->label('Email'),
]);

Popisky sloupců se použijí jako hlavičky, když jsou hlavičky zapnuté.

Exportovaný dotaz

exportTable() vychází z aktuálního filtrovaného a seřazeného dotazu tabulky, bez stránkování.

Pro přidání omezení jen pro export:

TableExport::make()
->fileName('active-users')
->modifyQueryUsing(fn ($query) => $query->where('active', true));

Pro export úplně samostatného dotazu použijte TableExport přímo:

return TableExport::make()
->fileName('inactive-users')
->query(User::query()->where('active', false))
->columns([
TextColumn::make('name'),
TextColumn::make('email'),
])
->download();

Exportované souhrny

Sloupce se souhrny v rozsahu query připojí své součty za datové řádky — stejné celkové součty, jaké patička zobrazuje pro celou filtrovanou sadu, v každém formátu (CSV, Excel, PDF). Buňky se vykreslí jako Label: hodnota ve sloupci, kam patří; sloupec s několika souhrny vyprodukuje několik řádků:

Number,Total
ORD-1,100
ORD-2,250
,"Grand total: 350 Kč"
,"Average: 175 Kč"

Souhrny v rozsahu page/selection popisují přechodný stav UI a nikdy se neexportují. Pro export holých dat bez součtů:

TableExport::make()
->withSummaries(false);

Rollup sloupce (->sums(), ->counts(), …) exportují své hodnoty za každý řádek i celkové součty. Při exportu vlastního dotazu s rollup sloupci musí dotaz obsahovat odpovídající withSum/withCount — stejný požadavek jako u samotné tabulky. Celkové součty podřádků a mezisoučty skupin jsou jen v patičce a do exportů se nezahrnují.

Volby CSV

TableExport::make()
->fileName('users')
->delimiter(';')
->enclosure('"')
->withHeadings();

Pro odstranění řádku hlaviček:

TableExport::make()
->withHeadings(false);

Excel export

Excel export používá formát xlsx.

<button type="button" wire:click="exportTable('xlsx')">
Export Excel
</button>

Nainstalujte OpenSpout, když vaše aplikace potřebuje skutečné XLSX soubory:

composer require openspout/openspout

Pokud OpenSpout není nainstalován, Wire spadne zpět na CSV výstup.

PDF export

PDF export používá formát pdf.

TableExport::make()
->fileName('users')
->orientation('landscape')
->paperSize('A4')
->pdfView('exports.users');

Nainstalujte Laravel DomPDF, když vaše aplikace potřebuje PDF soubory:

composer require barryvdh/laravel-dompdf

Pokud DomPDF není nainstalován, Wire spadne zpět na CSV výstup.

Data PDF pohledu

Při použití vlastního PDF pohledu ho navrhněte jako běžnou Blade export šablonu. Exportér předá pohledu headings, rows, columns a summaryRows (předformátované řádky součtů, prázdné když jsou souhrny vypnuté).

{{-- resources/views/exports/users.blade.php --}}
<table>
@if (! empty($headings))
<thead>
<tr>
@foreach ($headings as $heading)
<th>{{ $heading }}</th>
@endforeach
</tr>
</thead>
@endif
 
<tbody>
@foreach ($rows as $row)
<tr>
@foreach ($row as $value)
<td>{{ $value }}</td>
@endforeach
</tr>
@endforeach
</tbody>
 
@if (! empty($summaryRows))
<tfoot>
@foreach ($summaryRows as $summaryRow)
<tr>
@foreach ($summaryRow as $value)
<td>{{ $value }}</td>
@endforeach
</tr>
@endforeach
</tfoot>
@endif
</table>

Export na frontě

Download je response a job žádnou nevrací. Export na frontě je proto jiné doručení, ne totéž přesunuté jinam: zapíše soubor na disk a uživateli řekne, kde je.

public function exportInBackground(): void
{
$this->queueTableExport('csv', 's3', 'exports/orders');
}

Uživatel dostane „export se připravuje“ hned a druhou notifikaci se jménem souboru, až worker doběhne — přesně proto existuje databázový driver notifikací: než velký export skončí, není už kam blikat, žádný request nezbyl.

Stav cestuje s jobem. Bez toho by worker namountoval čerstvou komponentu a vyexportoval celou tabulku, takže kdo si ji vyfiltroval na dvacet řádků, dostane všech deset tisíc — v souboru natolik věrohodném, že to nikdo nezkontroluje.

$this->queueTableExport(
format: 'xlsx',
disk: 's3', // null použije filesystems.default
directory: 'exports',
);

Job veze třídu komponenty a formát, nikdy dotaz: dotaz jsou closury a builder a ani jedno serializaci nepřežije. Hostitel se postaví znovu a je požádán o svůj filtrovaný dotaz, takže soubor odpovídá datům v okamžiku běhu jobu, ne v okamžiku kliknutí.

Každý exportér zapisuje jednou metodou, writeTo(string $path, ...), kde php://output je cesta jako každá jiná — download a soubor na disku jsou proto tytéž řádky, tytéž sloupce a tytéž souhrny. Vlastní exportér ji musí implementovat:

class JsonExporter implements Exporter
{
public function writeTo(string $path, Builder $query, array $columns, array $summaryRows = []): void
{
// ...
}
 
public function extension(): string
{
return 'json';
}
 
public function export(Builder $query, array $columns, string $fileName, array $summaryRows = []): StreamedResponse
{
return response()->streamDownload(
fn () => $this->writeTo('php://output', $query, $columns, $summaryRows),
$fileName,
);
}
}

Exportér si příponu pojmenuje sám, protože formát není vždycky to, co se opravdu zapíše: ExcelExporter bez OpenSpout degraduje na CSV a uložený soubor jménem .xlsx s CSV uvnitř je lež, která vyplave až mnohem později, když ho někdo konečně otevře. Download se přejmenovává ze stejného důvodu.

Cesta, do které se zapsat nedá, vyhodí výjimku. writeTo() na špatnou cestu odpoví RuntimeException s jejím jménem, a stejně tak store(), když soubor, který právě zapsal, není čím přečíst zpátky:

try {
$path = TableExport::make()->format(ExportFormat::Excel)->store(disk: 's3');
} catch (RuntimeException $e) {
// "Could not open [/var/exports/orders.xlsx] to write the export to."
report($e);
}

Vlastní exportér má dělat totéž. Alternativou je nulabajtový soubor pod správným jménem a notifikace, že je export hotový — export na frontě nemá odpověď, kterou by si uživatel přečetl, takže „nezapsalo se nic“ a „zapsal se soubor“ jsou pro něj nerozlišitelné, pokud se selhání nevyhodí.

Úprava exportu, který nevlastníte

Tabulka z nainstalovaného modulu deklaruje svůj vlastní export a aplikace ho zúží přes hook export.configuring, místo aby tu třídu nahradila:

$manager->hook(Hook::ExportConfiguring, function (ExportConfiguringPayload $payload) {
$payload->query->whereNotNull('approved_at');
$payload->columns = array_filter($payload->columns, fn ($c) => $c->getName() !== 'cost');
 
return $payload;
}, for: 'invoices');

Běží uvnitř buildTableExport(), které volá exportTable() i queueTableExport(), takže stažení a zařazený soubor zůstanou jedním exportem, ne dvěma, které se dnes náhodou shodují. Viditelnost sloupců už je aplikovaná, takže callback dostane to, co by soubor obsahoval — ne všechno, co tabulka deklaruje.

Související dokumentace

Dokument Co pokrývá
Přehled tabulek Nastavení a stav tabulky
Sloupce Popisky sloupců, viditelnost a formátování
Filtry Filtrované dotazy použité exportem
Souhrny Součty připojené k exportům
Autorizace Omezení akcí exportu podle uživatele