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 协议》,转载必须注明作者和本文链接
本帖由系统于 1年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 30

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

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

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

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

感谢分享!

1年前 评论

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

1年前 评论
ThinkCsly

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

1年前 评论

感谢分享

1年前 评论

implements为ToCollection,方法应为collection

1年前 评论

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

1年前 评论
GitPush (楼主) 1年前
haowt (作者) 1年前
GitPush (楼主) 1年前
DuJianjun 1年前
user02 11个月前
final_dzg 9个月前

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

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

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

1年前 评论
GitPush (楼主) 1年前
fenglin 1年前
Jinson 1年前
user02 11个月前
final_dzg 9个月前

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

1年前 评论
fenglin 1年前

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

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

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

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

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

1年前 评论

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

1年前 评论
chris_zqw 1年前

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

1年前 评论

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

1年前 评论
echoyl 1年前

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

我文件里是这样的: file

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

1年前 评论
ryanxia 1年前
springlee 1个月前

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

1年前 评论

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

1年前 评论
springlee 1个月前

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

1年前 评论
user02 11个月前
final_dzg 9个月前

可以发一下demo吗?谢谢

1年前 评论

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

1年前 评论

WithStartRow 接口

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

@hedeqiang

11个月前 评论

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

10个月前 评论

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

10个月前 评论

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

file

10个月前 评论
final_dzg 9个月前

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

9个月前 评论
xuri

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

8个月前 评论

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

4个月前 评论

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

1个月前 评论

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