maatwebsite/Excel 3.1 使用教程 (导入篇)

maatwebsite/excel 使用教程 (导入篇)

官方文档

https://docs.laravel-excel.com/3.1/getting...

GIT 地址

https://github.com/maatwebsite/Laravel-Exc...

作为一个和 laravel 契合度很高的 excel 工具包,大家应该都是用过这个工具。特别是 2.x 版本几乎是用laravel框架都接触过,3.x 基本上全部重构,全网几乎找不到比较完善的教程,我就先抛砖引玉,大概把我用到的功能使用方式列一下,欢迎大家补充。

环境要求
  • PHP: ^7.0

  • Laravel: ^5.5

安装方式
composer require maatwebsite/excel

因为目前 3.1 只支持 Laravel 5.5 以上,所以会自动注册。

excel 导入

新建导入文件,导入导出业务代码尽量不要和原来业务耦合。我们拿官网 user 模块举例

php artisan make:import UsersImport --model=User

会在 app 目录下创建 Exports 目录

.
├── app
│   ├── Imports
│   │   ├── UsersImport.php
│ 
└── composer.json

UsersImport.php 代码内容

<?php

namespace App\Imports;

use App\User;
use Illuminate\Support\Facades\Hash;
use Maatwebsite\Excel\Concerns\ToModel;

class UsersImport implements ToModel
{
    /**
     * @param array $row
     *
     * @return User|null
     */
    public function model(array $row)
    {
        return new User([
           'name'     => $row[0],
           'email'    => $row[1], 
           'password' => Hash::make($row[2]),
        ]);
    }
}

业务控制器中调用

use App\Imports\UsersImport;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Controller;

class UsersController extends Controller 
{
    public function import() 
    {
        Excel::import(new UsersImport, 'users.xlsx');
    }
}

需要说明的是,上面所用的模式是 toModel,不需要手动去调用 save 方法,如果需要手动控制存储过程,请使用下列方法。

<?php

namespace App\Imports;

use App\User;
use Illuminate\Support\Facades\Hash;
//替换 toModel
use Maatwebsite\Excel\Concerns\ToCollection;

class UsersImport implements ToCollection
{
    /**
     * 使用 ToCollection
     * @param array $row
     *
     * @return User|null
     */
    public function ToCollection(Collection $rows)
    {
        //如果需要去除表头
        unset($rows[0]);
        //$rows 是数组格式
        $this->createData($rows);
    }

    public function createData($rows)
    {
        //todo
    }
}

Excel 导入基本功能到这基本完成,应该可以满足80%业务需求。如果有更多需求请继续阅读,下面将介绍分块导入、多表导入。

分块导入

如果 excel 数据量比较大,不适合一次性导入数据库,可以通过按量分块导入的方式节约内存。

按 1000 条为基准取出导入

namespace App\Imports;

use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
//新增
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class UsersImport implements ToModel, WithBatchInserts, WithChunkReading
{
    public function model(array $row)
    {
        return new User([
            'name' => $row[0],
        ]);
    }

    //批量导入1000条
    public function batchSize(): int
    {
        return 1000;
    }
    //以1000条数据基准切割数据
    public function chunkSize(): int
    {
        return 1000;
    }
}

需要注意的是 批量导入 只支持 ToModel 模式,如果你需要对数据进行更改,建议先批量导入临时表,再修改数据导入业务相关表。

多 sheet 导入

和导出比较类似,需要两步操作,第一步读取整体 excel 结构,第二步完成对应表数据导入。

第一个文件 UsersImport.php

namespace App\Imports;

use Maatwebsite\Excel\Concerns\WithMultipleSheets;

class UsersImport implements WithMultipleSheets 
{

    public function sheets(): array
    {
        //这里需要注意的是键,这个键可以是sheet表的名称,比如 'sheet1'=> new FirstSheetImport()
        return [
            0 => new FirstSheetImport(),
            1 => new SecondSheetImport(),
        ];
    }
}

这里我没有找到获取所有 sheet 的方法,所以只能一个个指定,如果你调用的方法是一致的,可以参考以下我的写法。如果你有更好的方式,欢迎交流。

public function sheets(): array
{
    $sheet = [];
    for ($i=1; $i<=26; $i++) {
        $sheet[$i] = new CustomSheetImport();
    }
    return $sheet;
}

第二个文件处理数据

namespace App\Imports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

class FirstSheetImport implements ToCollection
{
    public function collection(Collection $rows)
    {
        //todo
    }
}

其他比如数据验证之类的方法我觉得还是不要使用它提供的方式,大部分业务环境不需要这些额外繁琐的东西。
LNCODE
如果你有其他需要分享的功能模块欢迎在评论提出,我会更新文档。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 58

Tocollection 部分正确???写个guide是怕人学会了咋的

4年前 评论
GitPush (楼主) 4年前

Tocollection 部分正确???写个guide是怕人学会了咋的

4年前 评论
GitPush (楼主) 4年前

感谢分享!

4年前 评论

您好,请问如何获取导入的excel中的图片呢?

4年前 评论
ThinkQ

如果存在了,可以跳过吗?

4年前 评论

感谢分享

4年前 评论

implements为ToCollection,方法应为collection

4年前 评论

我还想问下,如果导入的时候想传入自己的参数,需要怎么处理?
举个例子:
我上传一个文件后进行上传,我会先生成一条批量导入的记录表,记录导入文件的位置,暂且定义为project(id,path).
然后将需要导入的excel内容导入到另外一张表,同时需要关联project的id。在导入的时候可以直接传入这个参数吗?

4年前 评论
GitPush (楼主) 4年前
haowt (作者) 4年前
GitPush (楼主) 4年前
DuJianjun 3年前
final_dzg 3年前

excel里带图片的时候如何导入

4年前 评论
GitPush (楼主) 4年前

如何将excel表中的第一行说明文字删除?

4年前 评论
GitPush (楼主) 4年前
fenglin 4年前
Jinson 3年前
user02 3年前
final_dzg 3年前

我用接口调,但是导入完成后怎么向接口返回数据,好像return输不出东西

4年前 评论
fenglin 4年前

你好,请问我excel中存有关联表的数据,我用什么方式导入呢?

4年前 评论
GitPush (楼主) 4年前

导入的数据文件如果是在oss服务器上,能用么

4年前 评论
GitPush (楼主) 4年前

导入 如何 传递参数 到 model 中 ?

3年前 评论

导入后时间变成了数字怎么处理

3年前 评论
巴啦啦小仙女 3年前

为什么在导入中文内容时 当前字段返回值 =false???3.0的版本

3年前 评论

file 读取xlsx文件,发现多了两行空行,这是为什么?xlsx文件是wps生成的

3年前 评论
echoyl 3年前

楼主,请问如何读正确的时间呢?

我文件里是这样的: file

后台接收 打印出来这样的: file

3年前 评论
springlee 2年前
ryanxia 3年前

多个sheet 如何不创建sheet文件啊???

3年前 评论

支持大批量数据导出吗,50W+

3年前 评论
springlee 2年前

我有一个问题,Excel 中第一行是表头,但是每次都会读取到第一行,插入的时候会插入第一行表头,如何过滤掉

3年前 评论
user02 3年前
final_dzg 3年前

可以发一下demo吗?谢谢

3年前 评论

文件上传出现异常:Start row (2) is beyond highest row (1) , 超出最大行数是什么鬼?

3年前 评论

WithStartRow 接口

use Maatwebsite\Excel\Concerns\WithStartRow;
.
.
.
class User implements ToModel,WithStartRow 
{
.
.
 //  从第二行开始
    public function startRow(): int
    {
        return 2;
    }
}

@hedeqiang

3年前 评论

这个组件对大规模的数据导入导出 , 不支持 , 数据稍微大一点都会爆掉 . 50W的单列数据导出都爆掉.直接导txt省心.

3年前 评论

如果excel里面有计算公式 怎么处理啊?

3年前 评论

多表导入 FirstSheetImport 里处理数据,有错误信息改如何返回给控制器?我这样调用里面可以读取数据,但是错误信息无法返回,请教下改如何返回呢?

file

3年前 评论
final_dzg 3年前

q请问执行php artisan make:import UsersImport --model=User;,没有生成App\User文件,是什么问题?

3年前 评论
xuri

推荐一个功能丰富、兼容性好、高性能的 Excel 文档基础库:github.com/xuri/excelize

3年前 评论

请问 Excel::import这个怎么返回我model中计算的导入数据的种类数量,我在model中统计好了数据,比如返回张三有100条数据,李四有200条数据?

3年前 评论

我如果不知道导入的excel到底有多少sheet怎么去处理呢?
想获取excel到底有几个sheet 然后根据业务去处理,因为sheet是不确定的,看文档上些的0,1,2 感觉都是知道有几个sheet

2年前 评论

我这边用的是 mongodb,导入时一直有个报错 Call to a member function beginTransaction() on null。google 了很多,但是没有得到解决,哪位大佬帮忙看下?我用的三方库是 jenssegers/mongodb

2年前 评论

为什么我觉得3.x版本很变态呢?导入excel还必须要建一个表,有一个对应的model是吗?

load 方法没有了;上传Excel文件后光读取内容,不写表不建model,只是纯粹读取excel内容怎么读取呢?

6个月前 评论

关于获取所有 sheet 及sheet数量的方法。
有动到原码。
需要的可以参考。
vendor/maatwebsite/excel/src/Reader.php 的 loadSpreadsheet 方法

file

Laravel

2个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!