laravel-admin 是一個可以快速幫你構建後臺管理的工具,它提供的頁面元件和表單元素等功能,能幫助你使用很少的程式碼就實現功能完善的後臺管理功能。
laravel-admin是一個基於laravel
外掛,可以幫助我們快速的構建後臺管理系統。我們今天來介紹一下使用laravel-admin來匯出excel檔案,基於laravel-admin 1.5版本。
laravel-admin內建了簡單的匯出模型中資料的工具,但樣式和格式比較簡單,而且中文亂碼,不太符合我們的要求。所以我們就來自定義匯出。
laravel-admin 文件--資料匯出 一節中,可以看到我們是可以使用第三方類庫來自定義匯出方式的。文件上也寫了一個簡單的例子, 我們來優化一下文件上的例子,使其更具有通用性。
我們先來看看文件上的例子
<?php
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));
});
}
複製程式碼
- 在頁面上執行匯出操作即可
增加表頭
同剛才一樣,我們再增加一個欄位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');
複製程式碼
結語
經常逛掘金,第一次寫文章,寫的內容比較簡單,提供一種思路供大家參考。如果有錯誤的地方,歡迎大家支出,不吝賜教。