You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel(PHP)中将Excel表格内的图片上传至服务器与数据库?

嘿,我之前刚好处理过类似的Excel图片导入需求,用Laravel生态里最常用的maatwebsite/excel包就能搞定,下面是一步步的实现方案,你可以参考:

处理Laravel中Excel图片上传到服务器与数据库的具体步骤

首先确认你已经安装了maatwebsite/excel(如果没装,先跑composer require maatwebsite/excel),毕竟你已经会处理文本导入,应该已经在用这个包了。

1. 编写/修改你的Excel导入类

核心是在导入类里提取Excel中的嵌入图片,存储到服务器后把路径存进数据库。假设你的Excel结构是:A列=产品名称,B列=价格,C列=嵌入的产品图片,示例代码如下:

namespace App\Imports;

use App\Models\Product;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithImages;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;

class ProductsImport implements ToModel, WithHeadingRow, WithImages
{
    public function model(array $row)
    {
        $imagePath = null;

        // 检查当前行的产品图片列是否是嵌入的图片对象
        if (isset($row['产品图片']) && $row['产品图片'] instanceof MemoryDrawing) {
            $image = $row['产品图片'];
            
            // 生成唯一且友好的文件名,避免重复
            $fileName = Str::slug($row['产品名称']) . '-' . time() . '.' . $image->getExtension();
            
            // 把图片存储到storage/app/public/products目录下
            // 记得提前执行`php artisan storage:link`,让public目录能访问storage里的文件
            Storage::disk('public')->put('products/' . $fileName, $image->getContent());
            
            // 生成前端可访问的路径,存到数据库
            $imagePath = 'storage/products/' . $fileName;
        }

        // 实例化Product模型,存入数据库
        return new Product([
            'name'     => $row['产品名称'],
            'price'    => $row['产品价格'],
            'image_url'=> $imagePath,
        ]);
    }

    // 可以指定哪一列是图片列,帮包更快定位图片(可选,但推荐)
    public function images()
    {
        return [
            '产品图片' => 'C:C', // 对应Excel里的C列
        ];
    }
}

2. 几个关键注意事项

  • 存储链接:一定要执行php artisan storage:link,不然前端无法访问你存在storage/app/public里的图片。
  • 错误处理:图片存储可能失败(比如权限不足、磁盘满),建议加个try-catch捕获异常:
    try {
        Storage::disk('public')->put('products/' . $fileName, $image->getContent());
        $imagePath = 'storage/products/' . $fileName;
    } catch (\Exception $e) {
        // 记录日志,或者标记这条数据导入失败
        \Log::error('产品图片存储失败: ' . $e->getMessage());
        $imagePath = null;
    }
    
  • 大文件性能:如果Excel里有几百上千条带图片的数据,建议加上WithChunkReading特性分批处理,避免内存溢出:
    use Maatwebsite\Excel\Concerns\WithChunkReading;
    
    class ProductsImport implements ToModel, WithHeadingRow, WithImages, WithChunkReading
    {
        // 每次处理100行
        public function chunkSize(): int
        {
            return 100;
        }
    
        // 其他代码不变...
    }
    
  • 外部链接图片:如果你的Excel里的图片是外部URL(不是嵌入的),那更简单——直接拿到URL,用Storage::putFileAs()或者第三方工具下载到服务器,再存路径就行。

3. 控制器里的调用代码

和你之前处理文本导入的逻辑几乎一样,没什么变化:

use App\Imports\ProductsImport;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Http\Request;

public function importProducts(Request $request)
{
    $request->validate([
        'file' => 'required|mimes:xlsx,xls',
    ]);

    Excel::import(new ProductsImport, $request->file('file'));

    return back()->with('success', '产品数据导入完成!');
}

额外优化建议

如果需要对图片做压缩、加水印之类的处理,可以用intervention/image包,在存储前处理图片:

use Intervention\Image\Facades\Image;

// 替换原来的Storage::put代码
$imageContent = $image->getContent();
// 压缩图片到宽度300px,保持比例,质量80%
$processedImage = Image::make($imageContent)->resize(300, null, fn($constraint) => $constraint->aspectRatio())->encode('jpg', 80);

Storage::disk('public')->put('products/' . $fileName, $processedImage);

内容的提问来源于stack exchange,提问作者user7747472

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:14:18