Dcat Admin 实现 Excel 数据导入

模态窗的使用

实现效果:

实现步骤

1. 安装 maatwebsite/excel

composer require maatwebsite/excel

2、创建excel文件导入逻辑脚本

具体使用参考:maatwebsite/excel 使用教程 (导入篇)

php artisan make:import Table5Import

导入逻辑如下:

<?php

namespace App\Imports;

use App\Models\Information5;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

class Table5Import implements ToCollection
{
    /**
     * @param Collection $collection
     */
    public function collection(Collection $collection)
    {
        $data = $collection->toArray();
        unset($data['0']);
        if (count($data) > 1) {
            $this->createData($data);
        }
    }

    // 具体导入业务代码
    public function createData($rows)
    {
        Information5::query()->delete();
        foreach ($rows as $key => $value) {
            if (!isset($value['4'])) {
                continue;
            }
            $model = new Information5();
            $model->bianhao = $value[0];
            $model->shuxiang = $value[1];
            $model->liangzicanshu = $value[2];
            $model->fabingnianriganzhi = $value[3];
            $model->xingbie = $value[4];
            $model->zihao = $value[5];
            $model->beizhu = (string)$value[6];
            $model->status = 1;
            $model->save();
        }
    }
}

3、Dcat Admin 创建工具表单

用作Excel文件上传表单

php artisan admin:form Information5ImportForm

默认会在 app/Admin/Forms 目录下创建 Information5ImportForm.php文件

修改如下:

<?php

namespace App\Admin\Forms;

use App\Http\Helpers\FunctionHelper;
use App\Imports\Table5Import;
use Dcat\Admin\Widgets\Form;
use Maatwebsite\Excel\Facades\Excel;

class Information5ImportForm extends Form
{
    /**
     * 上传文件数据逻辑处理
     * Handle the form request.
     *
     * @param array $input
     *
     * @return mixed
     */
    public function handle(array $input)
    {
        set_time_limit(0);
        //上传文件位置,这里默认是在storage中,如有修改请对应替换
        $file = storage_path('app/' . $input['file']);
        Excel::import(new Table5Import, $file); # 导入
        return $this->response()->success('数据导入成功')->refresh();
    }

    /**
     * 文件上传表单
     * Build a form here.
     */
    public function form()
    {
        $this->file('file', '上传数据(Excel)')->rules('required', ['required' => '文件不能为空'])->disk('local')->move(FunctionHelper::filePath());
    }

    /**
     * The data of the form.
     *
     * @return array
     */
    public function default()
    {
        return [
            'name' => 'John Doe',
            'email' => '[email protected]',
        ];
    }
}

4、Dcat Admin 创建自定义动作

php artisan admin:action

#运行成功之后会看到命令窗口出现如下信息,让开发者选择一个 Action 类的类型,这里我们输入 0 就行

# default 类型的动作类,可以用在页面的任意位置。

 Which type of action would you like to make?:
  [0] default
  [1] grid-batch
  [2] grid-row
  [3] grid-tool
  [4] form-tool
  [5] show-tool
  [6] tree-tool
 > 0 # 输入 0
#接着输入 Action 类名称,这里需要输入 大驼峰 风格的英文字母

 Please enter a name of action class:
 > Information5Import
#类名输入完成之后会出现以下信息让开发者输入类的命名空间,默认的命名空间是 App\Admin\Actions,这里我们直接按回车跳过就行了

 Please enter the namespace of action class [App\Admin\Actions]:
 >
#这样一个 Action 类就创建完成了,刚刚创建的类路径是 app/Admin/Actions/Information5Import.php

自定义动作逻辑,弹出文件上传模态框

<?php

namespace App\Admin\Actions;

use Dcat\Admin\Actions\Action;
use Dcat\Admin\Traits\HasPermissions;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Dcat\Admin\Admin;
use App\Admin\Forms\Information5ImportForm;

class Information5Import extends Action
{
    /**
     * @return string
     */
    protected $title = '<button class="btn btn-white">Excel 数据导入</button>';

    public function render()
    {
        $id = "reset-pwd"; # 每个action有唯一的id

        // 点击按钮,弹出模态窗
        $this->modal($id);

        return <<<HTML
<span class="grid-expand" data-toggle="modal" data-target="/topic/Laravel/1j6y0dje2k.html#{$id}">
   <a href="javascript:void(0)"><button class="btn btn-outline-info ">上传Excel并导入数据</button></a>
</span>
HTML;
    }

    # 模态框
    protected function modal($id)
    {
        $form = new Information5ImportForm();

        Admin::script('Dcat.onPjaxComplete(function () {
            $(".modal-backdrop").remove();
            $("body").removeClass("modal-open");
        }, true)');

        // 通过 Admin::html 方法设置模态窗HTML
        Admin::html(
            <<<HTML
<div class="modal fade" id="{$id}">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">导入数据</h4>
         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      </div>
      <div class="modal-body">
        {$form->render()}
      </div>
    </div>
  </div>
</div>
HTML
        );
    }

    /**
     * @return string|array|void
     */
    public function confirm()
    {
        // return ['Confirm?', 'contents'];
    }

    /**
     * @param Model|Authenticatable|HasPermissions|null $user
     *
     * @return bool
     */
    protected function authorize($user): bool
    {
        return true;
    }

    /**
     * @return array
     */
    protected function parameters()
    {
        return [];
    }
}

5、在页面工具栏添加导入按钮

文件 app/Admin/Controllers/Information5Controller.php

<?php

use App\Admin\Actions\Information5Import;

class Information5Controller extends AdminController
{
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        return Grid::make(new Information5(), function (Grid $grid) {
            $grid->tools(function (Grid\Tools $tools) {
                //Excel导入
                $tools->append(new  Information5Import());
            });
        });
    }
}

引用链接

[1] maatwebsite/excel 使用教程 (导入篇): https://www.wangmaolin.net/books/php/page/maatwebsiteexcel