本文推荐使用和 Laravel 契合度很高的 maatwebsite/excel 工具包。
2.x 版本
环境要求
- PHP version >= 5.3.7
- Laravel >= 4.1
安装配置
安装 maatwebsite/excel 工具包:
在 config/app.php 中注册服务提供者到 providers 数组:composer require maatwebsite/excel ~2.1
在 config/app.php 中注册门面到 aliases 数组:Maatwebsite\Excel\ExcelServiceProvider::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
导出示例
``` use Excel;
$cellData = [ [‘学号’,’姓名’,’成绩’], [‘10001’,’AAAAA’,’99’], [‘10002’,’BBBBB’,’92’], [‘10003’,’CCCCC’,’95’], [‘10004’,’DDDDD’,’89’], [‘10005’,’EEEEE’,’96’], ];
Excel::create(‘学生成绩’, function($excel) use ($cellData){ $excel->sheet(‘score’, function($sheet) use ($cellData){ $sheet->rows($cellData); }); })->export(‘xls’);
<a name="Z7UcY"></a>
#### 导入示例
use Excel;
$filePath = ‘filePath’;
Excel::load($filePath, function($reader) { $data = $reader->all(); dd($data); });
<a name="l2R6o"></a>
### 3.x 版本
3.x 改版较大,基本重构。底层通过 Export 对象驱动,入口自定义 Export 类,实例化 FromCollection 接口,继承Exportale 特性。
<a name="mocI0"></a>
#### 环境要求
- PHP >= 7.0
- Laravel >= 5.5
<a name="hViZd"></a>
#### 安装配置
安装 maatwebsite/excel 工具包:
composer require maatwebsite/excel ~3.1
<a name="ii4Vl"></a>
#### 导出示例
新建导出数据表 user 的文件:
php artisan make:export UsersExport —model=User
app 目录下创建 Exports 目录:
├── app │ ├── Exports │ │ ├── UsersExport.php │ └── composer.json
UsersExport.php 文件内容:
<?php
namespace App\Exports;
use App\User; use Maatwebsite\Excel\Concerns\FromCollection;
class UsersExport implements FromCollection { public function collection() { return User::all(); } }
业务调用:
<?php
use App\Exports\UsersExport; use Maatwebsite\Excel\Facades\Excel; use App\Http\Controllers\Controller;
class UsersController extends Controller { public function export() { return Excel::download(new UsersExport, ‘users.xlsx’); } }
> 上述示例中,UsersExport 继承了 FromCollection 类,在 collection 方法中查询了 user 表,并导出 user 表数据。
但是在一些业务逻辑中,我们想直接导出自定义数组,这里我们可以用到 maatwebsite/excel 中 FromArray 类来实现此功能。<br />创建 CommonExport.php 导出文件:
php artisan make:export CommonExport
app 目录下创建 Exports 目录:
├── app │ ├── Exports │ │ ├── UsersExport.php │ │ ├── CommonExport.php │ └── composer.json
CommonExport.php 文件内容:
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
class CommonExport implements FromArray { public function array(): array { $data = [ [‘表题1’, ‘表题2’, ‘表题3’], [‘value1’, ‘value2’, ‘value3’], [‘value1’, ‘value2’, ‘value3’], [‘value1’, ‘value2’, ‘value3’] ]; return $data; } }
业务调用:
<?php
namespace App\Http\Controllers;
use App\Exports\CommonExport; use Maatwebsite\Excel\Facades\Excel;
class DemoController { public function demo() { return Excel::download(new CommonExport(), ‘demo.xlsx’); } }
上述示例中,CommonExport.php 文件我们可以做下封装:
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
表头
use Maatwebsite\Excel\Concerns\WithHeadings;
自动适应单元格宽
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class CommonExport implements FromArray, WithHeadings, ShouldAutoSize { protected $headers; protected $lists;
public function __construct(array $headers, array $lists)
{
$this->headers = $headers;
$this->lists = $lists;
}
public function array(): array
{
return $this->lists;
}
public function headings(): array
{
return $this->headers;
}
}
在业务层调用:
<?php
namespace App\Http\Controllers;
use App\Exports\CommonExport; use Maatwebsite\Excel\Facades\Excel;
class DemoController { public function demo() { $headers = [‘表题1’, ‘表题2’, ‘表题3’]; $lists = [ [‘value1’, ‘value2’, ‘value3’], [‘value1’, ‘value2’, ‘value3’], [‘value1’, ‘value2’, ‘value3’], [‘value1’, ‘value2’, ‘value3’] ]; return Excel::download(new CommonExport($headers, $lists), ‘demo.xlsx’); } }
注意,在上述的 CommonExport 封装类中,我们同时继承使用了自动适应单元格宽的 ShouldAutoSize 类。<br />Maatwebsite\Excel 工具包中提供了很多方法,如:自动适应单元格宽、单元格格式化、导出多 sheet、设置单元格高度以及垂直居中,字体颜色、背景色等、导出图片等等方法。这里我们就不一一介绍了,若使用可参考官方提供的文档。
<a name="cGC5T"></a>
#### 导入示例
新建导入数据库 user 表数据的文件:
php artisan make:import UsersImport —model=User
app 目录下创建 Imports 目录:
├── 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
}
}
> 以上示例中,我们使用 UsersImport 类直接添加数据到 user 表。
但是在一些业务逻辑中,我们想直接取出 Excel 表格中的数据,这里我们可以使用到 maatwebsite/excel 中 ToArray 类来实现此功能。<br />创建 CommonExport.php 导入文件:
php artisan make:import CommonImport
app 目录下创建 Imports 目录:
├── app │ ├── Imports │ │ ├── UsersImport.php │ │ ├── CommonImport.php │ └── composer.json
CommonImport.php 文件内容:
<?php
namespace App\Imports;
use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\ToCollection; use Maatwebsite\Excel\Concerns\ToArray;
class CommonImport implements ToArray { public function Array(Array $tables) { return $tables; } }
业务调用:
<?php
namespace App\Http\Controllers;
use App\Imports\CommonImport; use Maatwebsite\Excel\Facades\Excel;
class DemoController { public function demo() { $file = ‘D:\WWW\Study\Laravel\public\data\demo.xlsx’; $array = Excel::toArray(new CommonImport, $file); dd($array); } }
与导出一样,Maatwebsite\Excel 工具包中也提供了很多其他导入功能,如:分块导入、多 sheet 导入等方法。若使用可参考官方提供的文档。
<a name="HRjQe"></a>
### 问题汇总
> 因项目环境配置不同,以下解决方法仅供参考。
<a name="PmjdP"></a>
#### 导出空文件
date: 2020-04-13
Nginx Version: 1.14.0 PHP Version: v7.1.33 Laravel Version: 5.5 maatwebsite/excel Version: 3.1 ``` 主要原因:版本兼容问题。继承使用了自动适应单元格宽的 ShouldAutoSize 类。