情景描述
fastadmin有自带的导入功能,但是不好用,它要求你的表格标题必须跟数据表的备注一致,而且拿到的数据是直接插入数据表,我们无法获取想要的数据并对数据进行处理;而且有时候我们只是想要单纯的读取文件功能,系统自带的无法满足,所以需要对导入功能重写。
重写导入功能
1.打开导入按钮
在你的模板文件中,在工具栏添加import
功能即可,如果要自定义导入按钮,可以参考我的另一篇文章fastadmin后台自定义按钮和弹窗-CSDN博客
{:build_toolbar('refresh,add,edit,del,import')}
2.js文件添加导入接口链接
在后台对应功能的js文件初始化表格参数配置
中添加链接即可
// 初始化表格参数配置
Table.api.init({extend: {index_url: 'user/group/index',add_url: 'user/group/add',edit_url: 'user/group/edit',del_url: 'user/group/del',multi_url: 'user/group/multi',import_url: 'user/group/import', //导入接口链接table: 'user_group',}
});
3.重写import方法
-
(1)先在
application/admin/library/traits/Backend.php
文件中添加读取文件数据方法/*** 读取文件数据并返回* @return array*/protected function readFile($file){if (!$file) {$this->error(__('Parameter %s can not be empty', 'file'));}$filePath = ROOT_PATH . DS . 'public' . DS . $file;if (!is_file($filePath)) {$this->error(__('No results were found'));}//实例化reader$ext = pathinfo($filePath, PATHINFO_EXTENSION);if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {$this->error(__('Unknown data format'));}if ($ext === 'csv') {$file = fopen($filePath, 'r');$filePath = tempnam(sys_get_temp_dir(), 'import_csv');$fp = fopen($filePath, "w");$n = 0;while ($line = fgets($file)) {$line = rtrim($line, "\n\r\0");$encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);if ($encoding != 'utf-8') {$line = mb_convert_encoding($line, 'utf-8', $encoding);}if ($n == 0 || preg_match('/^".*"$/', $line)) {fwrite($fp, $line . "\n");} else {fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");}$n++;}fclose($file) || fclose($fp);$reader = new Csv();} elseif ($ext === 'xls') {$reader = new Xls();} else {$reader = new Xlsx();}//加载文件try {if (!$PHPExcel = $reader->load($filePath)) {$this->error(__('Unknown data format'));}$currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表$allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号$allRow = $currentSheet->getHighestRow(); //取得一共有多少行$maxColumnNumber = Coordinate::columnIndexFromString($allColumn);//读取第一行字段名$fields = [];for ($currentRow = 1; $currentRow <= 1; $currentRow++) {for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();$fields[] = $val;}}//读取行数据$row = [];for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {$values = [];for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {$val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();$values[] = is_null($val) ? '' : $val;}$row[] = array_combine($fields, $values);}} catch (Exception $exception) {$this->error($exception->getMessage());}if (!$row) {$this->error(__('No rows were updated'));}return $row;}
-
(2)在后台控制器中重写
import
方法,并调用上面的readFile
方法读取数据,然后就可以对数据进行处理/*** 重写import方法*/public function import(){$file = $this->request->request('file'); //'file'为文件字段名$data = $this->readFile($file);foreach ($data as $row){//do something//var_dump($row);}$this->success('导入成功');}
4.添加上传文件类型
如果是刚下载的框架,由于没有配置允许上传的文件类型,导入的时候会报错提示“上传文件格式受限制
”,则需要添加上传文件类型,直接在配置文件application/extra/upload.php
中的mimetype
添加需要的文件类型即可
/*** 可上传的文件类型*/'mimetype' => 'jpg,png,bmp,jpeg,gif,webp,zip,rar,wav,mp4,mp3,webm,xls,xlsx,csv',