yajra/laravel-datatables-buttons
Laravel DataTables Buttons plugin for server-side exports and printing. Add CSV, Excel, PDF, and print support to yajra/laravel-datatables with DataTables Buttons extension. Compatible with Laravel 12+ and PHP 8.3+.
yajra/laravel-datatables):
composer require yajra/laravel-datatables-buttons:^13
php artisan vendor:publish --tag=datatables-buttons
<!-- CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.dataTables.min.css">
<!-- JS -->
<script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.print.min.js"></script>
// app/Http/Controllers/UserController.php
use Yajra\DataTables\Facades\DataTables;
use App\Models\User;
public function anyData()
{
return DataTables::of(User::query())
->addColumn('action', function($user) {
return '<button class="btn btn-sm btn-primary">View</button>';
})
->add('buttons', function($user) {
return '<button class="btn btn-sm btn-success">Export</button>';
})
->make(true);
}
<!-- resources/views/users.blade.php -->
<table id="users-table" class="display">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
</table>
<script>
$(function() {
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('users.datatable') !!}',
buttons: [
{ extend: 'csv', text: 'Export CSV' }
]
});
});
</script>
// Controller
public function anyData()
{
return DataTables::of(User::query())
->addColumn('full_name', function($user) {
return $user->first_name . ' ' . $user->last_name;
})
->add('buttons', function($user) {
return '<button class="btn btn-sm btn-info">Edit</button>';
})
->rawColumns(['buttons'])
->make(true);
}
// app/DataTables/UserDataTable.php
use Yajra\DataTables\DataTables;
use Yajra\DataTables\Buttons;
class UserDataTable extends DataTables
{
public function __construct()
{
$this->buttons([
Buttons::export('Excel', 'Excel'),
Buttons::export('CSV', 'CSV'),
Buttons::make('customExport')
->className('btn btn-warning')
->action(function($query, $export) {
return $query->get()->map(fn($user) => [
'name' => $user->name,
'custom_data' => $this->formatCustomData($user),
]);
})
->exportOpenSingle(true)
->title('Custom Export'),
]);
}
protected function formatCustomData($user)
{
return json_encode($user->custom_data);
}
}
// Dynamic button visibility based on user role
public function buttons()
{
$buttons = [
Buttons::export('Excel', 'Excel'),
Buttons::export('CSV', 'CSV'),
];
if (auth()->user()->isAdmin) {
$buttons[] = Buttons::make('customExport')
->className('btn btn-danger')
->action(function($query) {
return $query->with('auditLogs')->get();
});
}
return $buttons;
}
// app/Http/Controllers/UserController.php
use App\Http\Resources\UserResource;
public function anyData()
{
return DataTables::of(User::query())
->addColumn('full_name', function($user) {
return UserResource::make($user)->full_name;
})
->make(true);
}
public function anyData()
{
return DataTables::of(User::query())
->addColumn('custom_header', function($user) {
return $user->created_at->format('Y-m-d');
})
->exportOptions([
'excel' => [
'title' => 'User Export',
'columns' => [
['data' => 'id', 'name' => 'ID'],
['data' => 'name', 'name' => 'Full Name'],
['data' => 'custom_header', 'name' => 'Registration Date'],
],
],
])
->make(true);
}
public function anyData()
{
return DataTables::of(User::query())
->exportOptions([
'excel' => [
'filename' => 'users_' . now()->format('Y-m-d') . '.xlsx',
],
'csv' => [
'filename' => 'users_' . now()->format('Y-m-d') . '.csv',
],
])
->make(true);
}
Missing Dependencies:
jQuery DataTables Buttons JS/CSS in your Blade view.CSRF Token Issues:
csrf: true to your DataTable initialization:
buttons: [
{ extend: 'excel', text: 'Export', csrf: true }
]
Memory Limits:
$this->buttons([
Buttons::export('Excel', 'Excel')
->setChunkSize(1000)
]);
Column Mismatch:
exportOptions:
->exportOptions([
'excel' => [
'columns' => [
['data' => 'id', 'name' => 'ID'],
['data' => 'name', 'name' => 'Name'],
],
],
])
Check Export Logs:
config/datatables.php:
'debug' => env('DATATABLES_DEBUG', false),
storage/logs/laravel.log.Verify Query:
toSql() and getBindings() to debug the query:
$query = User::query();
dd($query->toSql(), $query->getBindings());
Test with Small Data:
$this->buttons([
Buttons::export('Excel', 'Excel')
->setQuery(User::query()->limit(10))
]);
Custom Export Formats:
// app/Exports/CustomExport.php
use Yajra\DataTables\Buttons\Export\Export;
use Maatwebsite\Excel\Facades\Excel;
class CustomExport extends Export
{
public function export()
{
return Excel::download(new CustomExcelExport($this->collection), 'custom.xlsx');
}
}
Macros for Reusable Logic:
// app/DataTables/DataTableMacros.php
DataTables::macro('addCustomExport', function() {
return $this->buttons([
Buttons::make('customExport')
->className('btn btn-info')
->action(function($query) {
return $query->get()->map(fn($item) => [
'id' => $item->id,
'custom_field' => $item->custom_field ?? 'N/A',
]);
}),
]);
});
Override Default Config:
config/datatables-buttons.php:
'export' => [
How can I help you explore Laravel packages today?