laravel-admin 是一个可以快速帮你构建后台管理的工具,它提供的页面组件和表单元素等功能,能帮助你使用很少的代码就实现功能完善的后台管理功能。
laravel-admin是一个基于
laravel
插件,可以帮助我们快速的构建后台管理系统。我们今天来介绍一下使用laravel-admin来导出excel文件,基于laravel-admin 1.5版本。
laravel-admin内置了简单的导出模型中数据的工具,但样式和格式比较简单,而且中文乱码,不太符合我们的要求。所以我们就来自定义导出。
laravel-admin 文档--数据导出
一节中,可以看到我们是可以使用第三方类库来自定义导出方式的。文档上也写了一个简单的例子,
我们来优化一下文档上的例子,使其更具有通用性。
我们先来看看文档上的例子
namespace
App
\
Admin
\
Extensions
;
use
Encore
\
Admin
\
Grid
\
Exporters
\
AbstractExporter
;
use
Maatwebsite
\
Excel
\
Facades
\
Excel
;
class
ExcelExpoter
extends
AbstractExporter
public
function
export
(
)
Excel
::
create
(
'Filename'
, function(
$excel
) {
$excel
->
sheet
(
'Sheetname'
, function(
$sheet
) {
$rows
=
collect
(
$this
->
getData
())->
map
(function (
$item
) {
return
array_only
(
$item
, [
'id'
,
'title'
,
'content'
,
'rate'
,
'keywords'
]);
$sheet
->
rows
(
$rows
);
})->
export
(
'xls'
);
复制代码
可以看到,他把文件名和导出的字段都定义好,这样就不具有灵活性了,总不能每个模型都要定义一个导出类吧?下面我们来优化一下
增加导出文件名和自定义导出字段
我们定义两个变量:
filename
和
fields
,并在构造函数中初始化
private $filename;
private $fields;
public function __construct(String $filename, Array $fields)
parent::__construct();
$this->filename = $filename;
$this->fields = $fields;
接着修改导出函数,使用这两个函数来替换写死的部分
* @return mixed|void
public function export()
Excel::create($this->filename, function ($excel){
$excel->sheet('Shee1', function($sheet) {
$rows = collect($this->getData())->map(function ($item) {
return array_only($item, $this->fields);
$sheet->rows($rows);
})->export('xls');
在控制器中使用导出函数
protected function grid()
return Admin::grid(User::class, function (Grid $grid) {
$grid->id('ID')->sortable();
$grid->mobile('手机号');
$grid->real_name('姓名');
$grid->privilege('级别')->display(function ($privilege){
return User::$privilegeInfo[$privilege];
$grid->department('部门')->display(function ($department){
return Department::where('id', $department)->value('name');
$fields = ['id', 'mobile', 'real_name', 'privilege', 'department'];
$grid->exporter(new ExcelExpoter('用户列表', $fields));
在页面上执行导出操作即可
这个时候我们打开导出的excel文件会发现,我们导出的文件没有表头。这就需要我们接下来的操作,增加表头。
同刚才一样,我们再增加一个字段title
用来表示表头字段,代码如下
private $title;
private $filename;
private $fields;
public function __construct(String $filename, Array $title, Array $fields)
parent::__construct();
$this->filename = $filename;
$this->title = $title;
$this->fields = $fields;
* @return mixed|void
public function export()
Excel::create($this->filename, function ($excel){
$excel->sheet('Shee1', function($sheet) {
$sheet->row(1, $this->title);
$rows = collect($this->getData())->map(function ($item) {
return array_only($item, $this->fields);
$sheet->rows($rows);
})->export('xls');
复制代码
接着在调用的地方加上表头字段
protected
function
grid
(
)
return
Admin
::
grid
(
User
::
class
, function (Grid
$grid
) {
......
$title
= [
'ID'
,
'手机号'
,
'姓名'
,
'级别'
,
'部门'
];
$fields
= [
'id'
,
'mobile'
,
'real_name'
,
'privilege'
,
'department'
];
$grid
->
exporter
(
new
ExcelExpoter
(
'用户列表'
,
$title
,
$fields
));
复制代码
重新执行导出操作,可以看到我们的文件中已经有了表头字段。
如果我们仔细看的话会发现一个问题,就是我们导出的字段是按照数据库中的顺序排列的,我们没办法指定字段的顺序。这也就导致我们写表头字段的时候也必须按照数据库中的顺序来写,否则就会导致字段和名字对不上的问题。举个例子:
数据库中的顺序如下:
'id', 'mobile', 'real_name', 'privilege', 'department'
复制代码
如果我们不知道数据库中字段的排列顺序或者其他的原因,写
title
字段时写成下面的格式
'姓名', 'ID', '手机号', '级别', '部门'
复制代码
就会导致导出的文件是错误。
针对这个问题,我们就需要来对结果按照一定的进行排序。
这里我是按照
fields
的顺序来排序,当然你也可以按照别的来排序,我这只是一种思路。
*
@return
mixed|void
public
function
export
(
)
Excel
::
create
(
$this
->filename, function (
$excel
){
$excel
->
sheet
(
'Shee1'
, function(
$sheet
) {
$sheet
->
row
(
1
,
$this
->title);
$rows
=
collect
(
$this
->
getData
())->
map
(function (
$item
) {
$item
=
array_only
(
$item
,
$this
->fields);
$row
= [];
foreach
(
$this
->fields
as
$field
) {
$row
[
$field
] =
$item
[
$field
];
return
$row
;
$sheet
->
rows
(
$rows
);
})->
export
(
'xls'
);
复制代码
代码比较简单,就是遍历
fields
数组,把每一列中对应的值取出来,就到达了排序的效果。
如果对excel文件的样式有要求,可以参照
laravel-excel
的
文档
来进行相关操作。
Excel
::
create
(
$this
->filename, function (
$excel
){
$excel
->
sheet
(
'Shee1'
, function(
$sheet
) {
$sheet
->
setWidth
(
array
(
'A'
=>
5
,
'B'
=>
12
,
$sheet
->
row
(
1
,
$this
->title);
$rows
=
collect
(
$this
->
getData
())->
map
(function (
$item
) {
$item
=
array_only
(
$item
,
$this
->fields);
$row
= [];
foreach
(
$this
->fields
as
$field
) {
$row
[
$field
] =
$item
[
$field
];
return
$row
;
$sheet
->
rows
(
$rows
);
})->
export
(
'xls'
);
复制代码
结语
经常逛掘金,第一次写文章,写的内容比较简单,提供一种思路供大家参考。如果有错误的地方,欢迎大家支出,不吝赐教。