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' ); 复制代码

    结语

    经常逛掘金,第一次写文章,写的内容比较简单,提供一种思路供大家参考。如果有错误的地方,欢迎大家支出,不吝赐教。