导入和导出对象
匿名 · 更新于 2021/6/28
整个 Laravel Excel 哲学围绕拥有Export和/或Import对象发展。
#目录结构
这些导入和导出类的位置如下:
. ├── app │ ├── Exports (Groups all exports in your app) │ │ ├── UsersExport.php │ │ ├── ProductsExport.php │ │ └── Sheets (You can group sheets together) │ │ ├── InactiveUsersSheet.php │ │ └── ActiveUsersSheet.php | | │ ├── Imports (Groups all imports in your app) │ │ ├── UsersImport.php │ │ ├── ProductsImport.php │ │ └── Sheets (You can group sheets together) │ │ ├── OutOfStockProductsSheet.php │ │ └── ProductsOnSaleSheet.php │ └── composer.json
#封装
这些对象封装了整个导出或导入过程。它背后的想法是,您可以在控制器、服务、作业、事件侦听器或命令中巧妙地使用这些对象。在所有这些情况下,导出/导入需要如何发生的整个逻辑都保存在此对象中。
#数据传输对象
导入/导出对象本质上是简单数据传输对象 (DTO)。这意味着他们会将您要导出/导入的信息传输到 Excel 编写器/阅读器。此信息不仅是您要导出的实际数据,还包括其他信息,例如文件样式、工作表名称、单元格的数字格式等。
在大多数情况下,这意味着您的代码不需要直接接触实际的读/写过程。
#普通的旧 PHP 对象
Besides being a DTO, the import/export objects are also just Plain Old PHP Objects (POPO). This means that you can do anything with them that you can do with normal PHP objects.
#Constructor
For instance, you can simply inject data through the constructor of the export object.
class UsersExport implements FromCollection {
private $year;
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">public</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">function</span> <span class="token function" style="color: rgb(240, 141, 73);">__construct</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span>int <span class="token variable" style="color: rgb(126, 198, 153);">$year</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">{</span>
<span class="token variable" style="color: rgb(126, 198, 153);">$this</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token property" style="color: rgb(248, 197, 85); font-style: italic !important;">year</span> <span class="token operator" style="color: rgb(103, 205, 204);">=</span> <span class="token variable" style="color: rgb(126, 198, 153);">$year</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">}</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">public</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">function</span> <span class="token function" style="color: rgb(240, 141, 73);">collection</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">{</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">return</span> Users<span class="token punctuation" style="color: rgb(204, 204, 204);">:</span><span class="token punctuation" style="color: rgb(204, 204, 204);">:</span><span class="token function" style="color: rgb(240, 141, 73);">whereYear</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token single-quoted-string string" style="color: rgb(126, 198, 153);">'created_at'</span><span class="token punctuation" style="color: rgb(204, 204, 204);">,</span> <span class="token variable" style="color: rgb(126, 198, 153);">$this</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token property" style="color: rgb(248, 197, 85); font-style: italic !important;">year</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token function" style="color: rgb(240, 141, 73);">get</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">}</span>
}
2
3
4
5
6
7
8
9
10
11
12
13
Excel::download(new UsersExport(2019), 'users.xlsx');
#Setters
Another option is to add setters for data that you want to pass.
class UsersExport implements FromCollection {
private $year;
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">public</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">function</span> <span class="token function" style="color: rgb(240, 141, 73);">setYear</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span>int <span class="token variable" style="color: rgb(126, 198, 153);">$year</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">{</span>
<span class="token variable" style="color: rgb(126, 198, 153);">$this</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token property" style="color: rgb(248, 197, 85); font-style: italic !important;">year</span> <span class="token operator" style="color: rgb(103, 205, 204);">=</span> <span class="token variable" style="color: rgb(126, 198, 153);">$year</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">}</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">public</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">function</span> <span class="token function" style="color: rgb(240, 141, 73);">collection</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">{</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">return</span> Users<span class="token punctuation" style="color: rgb(204, 204, 204);">:</span><span class="token punctuation" style="color: rgb(204, 204, 204);">:</span><span class="token function" style="color: rgb(240, 141, 73);">whereYear</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token single-quoted-string string" style="color: rgb(126, 198, 153);">'created_at'</span><span class="token punctuation" style="color: rgb(204, 204, 204);">,</span> <span class="token variable" style="color: rgb(126, 198, 153);">$this</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token property" style="color: rgb(248, 197, 85); font-style: italic !important;">year</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token function" style="color: rgb(240, 141, 73);">get</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">}</span>
}
2
3
4
5
6
7
8
9
10
11
12
13
$export = new UsersExport();
$export->setYear(2019);
Excel::download($export, 'users.xlsx');
2
3
4
#Getters
In similar fashion to setters, you can also add getters. This can potentially be useful if you want to keep a state of your export/import.
For instance, you can keep a row count in your users import.
namespace App\Imports;
use App</span>User;
use Maatwebsite</span>Excel</span>Concerns</span>ToModel;
class UsersImport implements ToModel
{
private $rows = 0;
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">public</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">function</span> <span class="token function" style="color: rgb(240, 141, 73);">model</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">array</span> <span class="token variable" style="color: rgb(126, 198, 153);">$row</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">{</span>
<span class="token operator" style="color: rgb(103, 205, 204);">++</span><span class="token variable" style="color: rgb(126, 198, 153);">$this</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token property" style="color: rgb(248, 197, 85); font-style: italic !important;">rows</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">return</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">new</span> <span class="token class-name" style="color: rgb(248, 197, 85);">User</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token punctuation" style="color: rgb(204, 204, 204);">[</span>
<span class="token single-quoted-string string" style="color: rgb(126, 198, 153);">'name'</span> <span class="token operator" style="color: rgb(103, 205, 204);">=</span><span class="token operator" style="color: rgb(103, 205, 204);">></span> <span class="token variable" style="color: rgb(126, 198, 153);">$row</span><span class="token punctuation" style="color: rgb(204, 204, 204);">[</span><span class="token number" style="color: rgb(240, 141, 73);">0</span><span class="token punctuation" style="color: rgb(204, 204, 204);">]</span><span class="token punctuation" style="color: rgb(204, 204, 204);">,</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">]</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">}</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">public</span> <span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">function</span> <span class="token function" style="color: rgb(240, 141, 73);">getRowCount</span><span class="token punctuation" style="color: rgb(204, 204, 204);">(</span><span class="token punctuation" style="color: rgb(204, 204, 204);">)</span><span class="token punctuation" style="color: rgb(204, 204, 204);">:</span> int
<span class="token punctuation" style="color: rgb(204, 204, 204);">{</span>
<span class="token keyword" style="color: rgb(204, 153, 205); font-style: italic !important;">return</span> <span class="token variable" style="color: rgb(126, 198, 153);">$this</span><span class="token operator" style="color: rgb(103, 205, 204);">-</span><span class="token operator" style="color: rgb(103, 205, 204);">></span><span class="token property" style="color: rgb(248, 197, 85); font-style: italic !important;">rows</span><span class="token punctuation" style="color: rgb(204, 204, 204);">;</span>
<span class="token punctuation" style="color: rgb(204, 204, 204);">}</span>
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
After doing the import, we can request the state with the getter.
$import = new UsersImport;
Excel::import($import, 'users.xlsx');
dd('Row count: ' . $import->getRowCount());
2
3
4
#Concerns
Most of the export/import configuration is done by using Concerns. Concerns are basically just simple interfaces. Implementing them will make the object adhere to a certain contract. This contract can request specific methods that e.g. data can be passed through. In other cases it might not ask for any methods to be implemented, but merely functions as a pointer interface.
Read more about Concerns in the concerns documentation.
#Hooks
In more complex cases you might want to hook into certain moments of the read/write process. This can be done by using Events. To register these events in your import/export object, you need to implement the Maatwebsite\Excel\Concerns\WithEvents concern.
namespace App\Exports;
use Maatwebsite</span>Excel</span>Concerns</span>WithEvents;
use Maatwebsite</span>Excel</span>Events</span>BeforeExport;
class UsersExport implements WithEvents
{
/**
* @return array
*/
public function registerEvents(): array
{
return [
// Handle by a closure.
BeforeExport::class => function(BeforeExport $event) {
// Do something before the export process starts.
},
];
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Alternatively, you can also configure these listeners globally if you want it to happen to any export.
Writer::listen(BeforeExport::class, function () {
// Do something before any export process starts.
});
2
3
