How to export excel after filter in laravel?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Export Only Filtered Data in Laravel using Maatwebsite/Excel
As a senior developer working within the Laravel ecosystem, one of the most common requirements developers face is exporting datasets that have been filtered or sorted. When using powerful packages like maatwebsite/excel alongside Eloquent, achieving this goal requires understanding how data flows between your application logic, the database, and the export mechanism.
The scenario you've described—attempting to export only filtered results generated in a Blade view—is a classic hurdle. While rendering a view is powerful for presentation, it often complicates direct data extraction for bulk operations like Excel exports.
This post will dive into why your initial approach might not be working as expected and provide the most robust, developer-friendly solution for exporting exactly the data you have filtered.
Understanding the Challenge: Why Direct Exporting Fails
You are using the FromView concern in your export class. This tells the Excel package to render a Blade view (export.blade.php) and dump the resulting HTML table into the spreadsheet.
The reason this often fails to apply filters correctly is that the filtering logic (the $users collection) is executed before the data reaches the export mechanism in a way that doesn't properly scope the export operation, or the filter context is lost during the final download step. When you use Excel::download(), it essentially takes whatever data is presented to it, and if your view logic isn't perfectly aligned with the export scope, you end up exporting the full dataset.
To reliably export only the filtered results, we must ensure that the filtering happens directly on the Eloquent query within the export class itself, rather than relying on rendering a separate view for the data structure.
The Recommended Solution: Filtering Within the Export Class
The most efficient and reliable method is to let the export class handle both the data retrieval and the formatting. Instead of rendering a Blade file for the table, we will iterate directly over the Eloquent collection that has already been filtered by your controller logic.
Step 1: Refactor the Export Class
We will modify FilterUserExport.php to accept the necessary scope or parameters and apply them directly to the query before iteration. Since you are filtering based on a search term, we can pass that term into the export class.
Here is how you can refactor your export logic:
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Modules\User\Entities\User;
use Illuminate\Support\Facades\DB; // Import DB facade for potential raw queries
class FilterUserExport implements FromCollection, WithEvents
{
protected $searchTerm;
// We inject the search term when the export is called
public function __construct(string $searchTerm = '')
{
$this->searchTerm = $searchTerm;
}
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
// Start with the base query
$query = User::query();
// Apply filtering based on the provided search term
if (!empty($this->searchTerm)) {
$query->where(function ($q) use ($this) {
$q->where('first_name', 'LIKE', '%' . $this->searchTerm . '%')
->orWhere('last_name', 'LIKE', '%' . $this->searchTerm . '%')
->orWhere('email', 'LIKE', '%' . $this->searchTerm . '%')
->orWhere('mobile', 'LIKE', '%' . $this->searchTerm . '%');
});
}
// Return the filtered collection directly
return $query->get();
}
/**
* @return array
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
// Example formatting event remains useful
$event->sheet->getDelegate()->setRightToLeft(true);
},
];
}
}
Step 2: Update the Controller Route and Logic
Now, your controller simply needs to retrieve the filtered data and pass it into the export mechanism. We remove the dependency on rendering a view entirely for this specific export type.
In UserController.php:
use App\Exports\FilterUserExport;
use Maatwebsite\Excel\Facades\Excel;
// ... other imports
public function exportFilteredUsers(Request $request)
{
$searchTerm = $request->input('search', '');
// 1. Perform the filtering on the database query
$filteredUsers = User::query();
if (!empty($searchTerm)) {
$filteredUsers->where(function ($query) use ($searchTerm) {
$query->where('first_name', 'LIKE', '%' . $searchTerm . '%')
->orWhere('last_name', 'LIKE', '%' . $searchTerm . '%')
->orWhere('email', 'LIKE', '%' . $searchTerm . '%')
->orWhere('mobile', 'LIKE', '%' . $searchTerm . '%');
});
}
// 2. Pass the filtered collection to the export class constructor
return Excel::download(new FilterUserExport($searchTerm), 'filtered_users.xlsx');
}
Step 3: Remove the View Dependency
Since the data is now being passed directly via the collection() method, you no longer need the Blade file (export.blade.php) or the FromView concern for this specific export type. This simplifies your code and makes it much more performant and maintainable.
Conclusion
Exporting filtered data in Laravel requires shifting focus from presentation (Blade views) to data retrieval (Eloquent queries). By leveraging the power of Eloquent directly within your export class, as demonstrated above, you ensure that the Excel file contains only the records matching the applied filters. This approach is cleaner, more idiomatic for Laravel development, and adheres to best practices when working with packages like maatwebsite/excel. For further deep dives into efficient data handling in Laravel, I highly recommend exploring resources on the official Laravel documentation.