PHP学习笔记—完成导出csv效率(附带打包zip教程)

对此众多的从事数码智能开发的同僚来说,从库中提取出多少后开展数据整理并且导出csv文件的意义是很广泛的,导出一个csv文件方便用此外的数额工具进行解析。所以在此地分享一下自我在劳作进度中已毕导出csv文件效用的长河与所获。

前言

PHP,第一,我被告知须求在laravel框架中落到实处下载接口这么些职务时,整个人是懵逼的,完全不清楚怎么初步去贯彻这些效应,然则对于一个理工科生来说,遇到难题并不吓人,剥丝抽茧,一步一步来。我分析,既然要促成下载作用接口,首先须求做的就是提供一个接口,而什么做一个接口我在<<Laravel使用体验–简易路由操作>>中已介绍,向前端提供一个URI即达到了接口的意义,其次是何等促成下载,最终是何许写入一个csv文件,本篇文章就从后五个样子介绍,并且最后附带PHP粤语件打包功效的兑现介绍

本来想打包作用独立写一篇博客的,后来意识这些职能完毕比较简单,而深层次的自身也暂时不会,就顺手本篇小说最终了

下载

一、通过传递HTTP报头完成下载

先是在度娘上找到的达成下载的章程之一:是通过向浏览器传递HTTP报头,告诉浏览器这几个URI的相关动作让浏览器去完毕。
HTTP报头是HTTP协议的一个部分,一般上用以客户端和服务端之间握手时的通信,通俗的精通就是
http服务器和客户端(一般为浏览器)之间数据传输此前的对话,告诉浏览器你想干什么。
而在PHP中落到实处HTTP报头参数传递成效的是header()方法,header()
函数向客户端发送原始的 HTTP
报头。其中认识到一些很重大,即必须在其他实际的出口被发送从前调用
header()
函数,例如在调用header()函数前不要写print_r()或var_dump()等函数。
传递报头参数的代码:

header("Content-type:text/csv");
header("Content-Disposition:attachment;filename=" . $start_date . '~' . $end_date . '_fare.csv');
header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
header('Expires:0');
header('Pragma:public');

中间第一行是告诉浏览器我索要导出文件,格式是csv,在Content-type以此参数类型中能够指定许多的导出文本的格式,例如rar、zip那样的回落包格式
传递那样的报头后,导出的公文的内容将是你在调用该header()函数的格局内的return值,例如return 123;则csv文件中就是123。
那种办法得以兑现下载,可是到底看上去不太美观,如此完美的laravel框架怎么可能会不关乎到下载格局的卷入呢,于是后来选用了另一种形式。

二、通过response方法落成下载

在看了其他前辈写的代码中,我发觉有一行代码

return reponse()->download($file)

看单词意思也清楚那行代码是起什么功能的。Response是laravel框架中的门面(facade),在这几个框架中是可以直接引用调用的成效
例如:

//响应重定向
Route::get('example/test24', function(){
    return Redirect::to('example/test21')->with('username', 'xiaoming');
});
//定制HTTP响应
Route::get('example/test21', function(){
    return Response::make('内容不存在', 404);
});
//响应视图
Route::get('example/test22', function(){
    return Response::view('test22');
});

以上的事例是response在封闭函数中的直接调用,在另外的地方本来也是可以直接选拔的,而下载文件就足以应用Response::download()方法
大家先看一下那个的源代码:

    /**
     * Create a new file download response.
     *
     * @param  \\SplFileInfo|string  $file
     * @param  string  $name
     * @param  array  $headers
     * @param  string|null  $disposition
     * @return \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse
     */
    public function download($file, $name = null, array $headers = [], $disposition = 'attachment');

可以看到这么些下载方式的参数,有$file, $name = null, array $headers = [], $disposition = 'attachment',后边都有默许值,可以不传递,也得以用来参数扩充,利用那么些点子就可以完成下载
例如:

public function getDownload()
{
    //PDF file is stored under project/public/download/info.pdf
    $file= public_path(). "/download/info.pdf";
    $headers = array(
              'Content-Type: application/pdf',
            );
    return Response::download($file, 'filename.pdf', $headers);
}

由此处的header()可以看看是讲求下载一个pdf文件,而在laravel
5框架中使用此成效还足以应用

return response()->download($file, 'filename.pdf', $headers);

这种措施,成效是一致的,其中也足以只指定第三个参数,那样下载的文本就是您的公文以前指定好的体系。

写入csv文件措施

介绍了怎样完结下载的二种办法,现在来说一下哪些将数据写入csv文件

字符串连接格局

先是要知道,csv文件的始末其实就是一串拼接起来的字符串,初阶指定好表头字符串,前边就以该表头的各种依次拼接数据即可,只是在表头和每一行数据的末尾都增进一个换行符\\n来达成表格对齐的效能即可。
例如:

$head_str = "日期,姓名,年龄,学校\\n";
$cnt  = count($data);
for ($i =0;$i<$cnt;$i++) {
        $tmp = implode(",",$data[$i]);
        $head_str .= $tmp."\\n";
}

其中$data是从库中取出的数码的二维数组,而每一个先是层索引指向的就是呼应的每一行数据,然后使用for巡回遍历取出每一行数据进行拼接。
这一种格局是和传递HTTP报头完毕下载的法门配合使用功效更好,因为在拼接达成后一贯在点子内return $head_str,就能将一切数据内容读入到了下载的csv文件中。当然,也得以动用fwrite()方法写入一个新文件$file,然后选拔response->download($file)措施下载该文件即可。

export()方法

新生意识,每趟这样拼接数据丰裕的难为,可以写一个共用的方式,以便在其余地点落到实处类似的成效时得以直接调用

    public static function exportData($data = array(), $title = [])
    {
        $new_data = [];
        if (!empty($data)) {
            if(empty($title))
            {
                foreach ($data as $key => $val) {
                    $new_data[$key] = isset($val) ?   mb_convert_encoding($val, 'gbk', 'utf-8') : '';
                }
            } else {
                foreach ($title as $key => $val) {
                    $new_data[$key] = isset($data[$key]) ? mb_convert_encoding($data[$key], 'gbk', 'utf-8') : '';
                }
            }
            $str =  implode(',', $new_data);
            fwrite(self::$fp, $str."\\n");
        }
    }

那一个主意的兑现原理是将数据开展转码处理然后选用fwrite()措施写入一个新文件。其中self::$fp是点名的文本的门径,那些php手册上看一下fwrite()措施的牵线就能分晓参数的意味。写入了新的文本后就足以再经过reponse->download()方法来下载了。

php文件打包教程

在数据量分外巨大时,三回性取出大批量的数码然后写入csv文件再下载的那几个流程是不适用的,因为数据量庞大会导致取数时间很长,命令运行超出内存。此时得以采纳的法门就是将大批量的数据按时间维度写入几个csv文件,然后再依照须求的流年距离将四个csv文件打包下载即可,所以在那也讲一下自身什么兑现文件打包。
在php中,利用的是ZipArchive()类,通过那么些类的实例化来贯彻打包。

照例是感兴趣的同校自行在php手册上读书

代码:

//获取zip包名
$zip_file = $save_path . '/' . $start_date . '-' . $end_date . '.zip';
if (file_exists($zip_file)) {
        return response()->download($zip_file);
}
//文件打包
$zip = new ZipArchive();
if ($zip -> open($zip_file, ZipArchive::CREATE) == true) {
        foreach ($file_dir as $file) {
             if (file_exists($file)) {
             $zip -> addFile($file, basename($file));
             }
        }
}
$zip -> close();

如此那般就落到实处了打包,其中$file_dir变量是你要打包的文本的路子数组,里面含有所有你想打包的公文路径,$zip_file变量是你想打包成zip文件的包的门路+名称。

局地同学在动用此措施时有时会随便用,以自我的经历,一般都是文本的途径不得法,或者是未曾点名相对路径
注意:在$zip -> addFile()措施中不用使用路径变量拼接,最好在动用该措施前就写好路子。使用了拼接不会报错,不过依旧会文件添加不进入,那里是一个大坑,我找了许久才发觉。

终极:本人新手程序员,一起前行!!!

相关文章