Easy Excel在Laravel7.*中导出EXCEL,中文文件名丢失的解决方案
2020-05-23 admin php laravel 2293
今天在laravel7.12版本中,使用了Easy Excel组件来读写excel文件。经查看git介绍,发现这是一个非常优秀的组件:Easy Excel是一个基于 box/spout 封装的Excel读写工具,可以帮助开发者更快速更轻松的读写Excel文件, 并且无论读取多大的文件只需占用极少的内存。
我们最早使用的phpexcel以速度慢、内存占用大而让开发者头疼,改进版的phpoffice读写速度有了较大提升,不过使用还是比较复杂。Easy Excel的使用非常简单,比如,读取excel并导入到mysql数据库,无需model直接可以分批导入:
public function handle(array $input) { $file = 'uploads/'.$input['file'];//上传的文件 $xmmc = str_replace(' ','',$input['xmmc']);//项目名称 $beizhu = str_replace(' ','',$input['beizhu']);//备注 $bm = 'a'.substr(md5($xmmc),16);//生成唯一正式表名 if (Schema::hasTable($bm)) {//如果临时数据表已存在,则删除 Schema::drop($bm); } // 分块导入表格数据 Excel::import($file)->each(function (SheetInterface $sheet)use($bm){ $sheet->chunk(1000, function (SheetCollection $collection)use($bm){ static $i = 1;//Static作用域,每次调用该函数时,该变量将会保留着函数前一次被调用时的值 $chunkArray = $collection->toArray(); if($i == 1){ //首次需要创建数据库 $keys = array_keys($chunkArray[2]); Schema::create($bm, function(Blueprint $table) use ($keys) { $table->increments('id');//主键 foreach($keys as $key => $value){ $value = str_replace(" ","",$value);//去除空格 $value = str_replace("'","",$value);//去除' $value = str_replace("`","",$value);//去除` $table->string($value)->nullable(); } }); } DB::table($bm)->insert($chunkArray); $i++; }); }); $sjl = DB::table($bm)->count(); if ($sjl > 0){ //写入seach表 $cxtj = Schema::getColumnListing($bm);//获取所有字段 array_splice($cxtj,0,1);//去除id $creatbgsx = new SeachModel; $creatbgsx->bm = $bm; $creatbgsx->xmmc = $xmmc; $creatbgsx->cxtj = $cxtj;//默认所有字段作为查询条件 $creatbgsx->kfcx = $cxtj;//开放全部字段查询 $creatbgsx->beizhu = $beizhu; $creatbgsx->save(); return $this->success('导入完成,请设置查询条件!', 'seach'); }else{ return $this->error('数据导入失败,请检查Excel内容是否合规!'); } }
导出更简单:
use Dcat\EasyExcel\Excel; $array = [ ['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'], ... ]; $headings = ['id' => 'ID', 'name' => '名称', 'email' => '邮箱']; // xlsx Excel::export($array)->headings($headings)->download('users.xlsx'); // csv Excel::export($array)->headings($headings)->download('users.csv'); // ods Excel::export($array)->headings($headings)->download('users.ods');
而在dcat admin中,导出只需要一句:
$grid->export()->filename('文件名.xlsx');
不过,在使用中发现,如果filename是中文的,将会过滤掉中文:
经仔细排查,发现了原因所在:basename函数不支持中文。具体文件在:
vendor/box/spout/src/Spout/Writer/WriterAbstract.php
需要注释掉这句:
$this->outputFilePath = $this->globalFunctionsHelper->basename($outputFileName);
然后改为:
$this->outputFilePath = $this->get_basename($outputFileName);
增加一个正则方法来替换basename:
//正则提取文件名,取代basename public function get_basename($filename) { return preg_replace('/^.+[\\\\\\/]/', '', $filename); }
这样就能正常导出中文名称的excel文件了。
补充:新版已修复了这个问题。