Learn how to import Excel files with images in Laravel using Maatwebsite Excel and PhpSpreadsheet. Step-by-step guide to extract images, validate rows, and store data with images into your database.
Uploading data through Excel files is a common feature in modern web applications. But what if your Excel file contains images along with data, and you want to save both the data and images into your Laravel application?
In this article, you'll learn how to import Excel data with embedded images in Laravel using the powerful Maatwebsite Excel package and the low-level capabilities of PhpSpreadsheet.
We'll cover:
Reading Excel data row by row
Extracting and saving images from Excel
Storing data into related models
Validating imported data
Saving images in your public directory
Let’s dive in.
Make sure you have the following setup:
Laravel 8+
maatwebsite/excel
package installed:
composer require maatwebsite/excel
PhpSpreadsheet (comes bundled with maatwebsite/excel
)
Imagine you're building a CRM or leaderboard system where each row in your Excel file includes:
A Name
A Email
A phone
An Image (avatar) embedded inside the Excel
Here's how you can achieve this using a custom import class.
php artisan make:import UserImport
Then open the newly created file and modify it like below.
namespace App\Imports;
use App\Models\User;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithValidation;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
class UserImport implements ToCollection, WithValidation
{
public function collection(Collection $rows)
{
$spreadsheet = IOFactory::load(request()->file('file'));
$images = $spreadsheet->getActiveSheet()->getDrawingCollection();
foreach ($rows as $key => $row) {
if ($key === 0) continue; // Skip the heading row
// Step 1: Extract and save the image
if ($images[$key - 1] instanceof MemoryDrawing) {
ob_start();
call_user_func(
$images[$key - 1]->getRenderingFunction(),
$images[$key - 1]->getImageResource()
);
$imageContents = ob_get_contents();
ob_end_clean();
$extension = match ($images[$key - 1]->getMimeType()) {
MemoryDrawing::MIMETYPE_PNG => 'png',
MemoryDrawing::MIMETYPE_GIF => 'gif',
MemoryDrawing::MIMETYPE_JPEG => 'jpg',
default => 'jpg'
};
} else {
$reader = fopen($images[$key - 1]->getPath(), 'r');
$imageContents = stream_get_contents($reader);
fclose($reader);
$extension = $images[$key - 1]->getExtension();
}
$filename = time() . ($key - 1) . '.' . $extension;
$path = public_path("admin/images/users/$filename");
file_put_contents($path, $imageContents);
$imageUrl = "/admin/images/users/$filename";
// Step 2: Create or update the user
User::updateOrCreate(
['email' => $row[1]],
[
'name' => $row[0],
'phone' => $row[2],
'avatar' => $imageUrl,
]
);
}
return true;
}
public function rules(): array
{
return [
'0' => 'required|string', // Name
'1' => 'required|email', // Email
'2' => 'required|string', // Phone
];
}
public function customValidationMessages()
{
return [
'0.required' => 'Name is required.',
'1.required' => 'Email is required.',
'1.email' => 'Invalid email format.',
'2.required' => 'Phone is required.',
];
}
}
use App\Imports\UserImport;
use Maatwebsite\Excel\Facades\Excel;
public function import()
{
request()->validate([
'file' => 'required|mimes:xlsx,xls'
]);
Excel::import(new UserImport, request()->file('file'));
return back()->with('success', 'Data imported successfully with images.');
}
Make sure the first row is the heading, and each image is placed properly in the corresponding row and column.
Image Index Misalignment: Images array is usually 0-indexed and starts below the heading, so using $key - 1
aligns rows with drawings.
Folder Permissions: Ensure public/admin/images/users
directory exists and is writable.
Large Files: For large files, consider queueing your import job using WithChunkReading
and ShouldQueue
interfaces.
Image Format Errors: PhpSpreadsheet supports JPEG, PNG, GIF. Avoid inserting BMP or SVG images.
Importing Excel data with images in Laravel may seem tricky at first, but with the combination of Maatwebsite Excel and PhpSpreadsheet, it's totally achievable.
Let your users upload full Excel files - and handle everything programmatically behind the scenes.