情景描述
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',