柔晶美网络工作室

柔晶美网络工作室,倾心于web技术的博客站点

关注我 微信公众号

您现在的位置是: 首页 > 博客日记

Easy Excel在Laravel7.*中导出EXCEL,中文文件名丢失的解决方案

2020-05-23 admin php  laravel  2267

今天在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文件了。

补充:新版已修复了这个问题。

文章评论


需要 登录 才能发表评论
热门评论
0条评论

暂时没有评论!