官方文档

​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 ToModel
{
/**
* 使用 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
}
}