zoukankan      html  css  js  c++  java
  • PHP之导出CSV文件

    序言

    Q1:什么是csv文件?

    A1:csv即 comma-separated values ,逗号分隔值。是一种通用的相对简单地文件格式,目前被较为广泛的使用。其最广泛的应用就是用来转移表数据。

    CSV”并不是一种单一的、定义明确的格式(尽管RFC 4180有一个被通常使用的定义)。因此在实践中,术语“CSV”泛指具有以下特征的任何文件:

    1.纯文本,使用某个字符集,比如ASCII、Unicode、EBCDIC或GB2312;

    2.由记录组成(典型的是每行一条记录);

    3.每条记录被分隔符分隔为字段(典型分隔符有逗号、分号或制表符;有时分隔符可以包括可选的空格);

    4.每条记录都有同样的字段序列

    Q2:什么是BOM?

    A2:BOM即为Byte Order Mark,字节顺序标记(详见百度百科)。在Windows自带的记事本等软件,当其在保存一个utf-8格式编码的文件时,就会默认在文件头加上三个不看见的字符(0xEF 0xBB 0xBF),来确保自身再次打开时,可以以utf-8格式来打开文件,从而杜绝乱码现象。在一般情况下来说,这并不会有什么大的麻烦,但是,对于本文的导出csv中,若导出数据为utf-8编码格式的,当导出的csv文件在windows系统打开时(尤其是用excel)打开时,就会出现乱码情况。所以,为了杜绝出现此类情况,请在导出到csv文件时,记得在文件的最头部加上BOM头,从而使得你导出的csv文件可以正确显示。

    正文:

    下面,分享一下如何使用PHP导出csv文件。

    大体思路是这样子的:由于csv文件是一种由逗号分隔字段的文件格式,所以,我们可以将准备导入的字段用逗号 “,” 隔开,在每一行的尾部加上” ”。

    此外还有一点需要注意的地方,那就是文件的BOM头,如果忽略了BOM头的话,你以UTF-8编码形式输出的csv文件在windows中打开很可能会是一堆乱码。该如何解决这个问题呢?一是运用转码函数iconv,将utf-8格式的字符串转换为gb2312格式的,这样在Windows下打开就不会乱码了,还有另外的一个思路就是在文件的开头加上BOM信息头,这样当在windows系统下打开这个文件时,系统就会得知这个文件的编码格式,从而避免了乱码输出的情况。

    而对于Csv文件的导出,经博主查看了各路大神的分享之后,对于csv文件的导出总结了大概这两种方法:

    方法一,直接以echo的形式直接输出:

    复制代码
    /*按csv文件的标准生成字符串,为了避免乱码,该方法使用了将utf-8格式的字符串转换为gb2312的方法
    *@param 
    *$content=array(
    *     'fields' => array(
    *                       'field1' => '字段1',
    *                     'field2' => '字段2',
    *                           ......       
    *
    *                      ),
    *       'data' => array(
    *                            0 =>array(
    *                                         'field1' => 'val01',
    *                                         'field2' => 'val02',
    *                                           ......
    *                                        ),
    *                            1 =>array(
    *                                         'field1' => 'val11',
    *                                         'field2' => 'val12',
    *                                           ......
    *                                        ),
    *                               ......
    *                       ),
    *
    *);
    *生成csv表样式为:
    *  字段1  字段2  字段3  字段4  ......
    *  val01  val02  val03  val04  ......
    *  val11  val12  val13  val14  ......
    *    .......
    */
    public function csvGenerator($content)
        {
    
    
            $str = '';//csv内容所保存的字符串
            foreach ($content['fields'] as $val) {
                $str .= (iconv('utf-8', 'gb2312', $val) . ",");//设置表头 将表头依次设置为字段1、字段2...
    
            }
            $str .= "
    ";
            foreach ($content['data'] as $kkk => $row) {
                foreach ($content['fields'] as $k => $v) {
                    $row[$k] = str_replace('"', '""', $row[$k]);
                    $str .= (iconv('utf-8', 'gb2312', $row[$k]) . ",");
                }
                $str = substr($str, 0, -1);//去掉每行最后一个逗号;
                $str .= "
    ";
            }
    
            return $str; //
        }

    复制代码
    复制代码
    /**导出csv文件(csv文件下载)直接echo的方法:
         *@param $filename
         * 输出csv文件的文件名
         * @param $data
         * 要写入csv文件的内容,即经过csvGenerator处理过的字符串;
         */
         function csvExport($filename='export.csv',$data){
    
            header("Content-type:application/csv");
            header("Content-Disposition:attachment;filename=".$filename);
            header("Cache-Control:must-revalidate,post-check=0,pre-check=0");
            header('Expires:0');
            header('Pragma:');
            echo $data;
            return true;
    
        }
    复制代码

    方法二,以文件的形式输出:

    复制代码
    /*按csv文件的标准生成字符串,这里并未对编码方式进行处理,而是采用了在文件头加BOM的方式,详见csvExportWithBOM函数
    *@param 
    *$content=array(
    *     'fields' => array(
    *                       'field1' => '字段1',
    *                     'field2' => '字段2',
    *                           ......       
    *
    *                      ),
    *       'data' => array(
    *                            0 =>array(
    *                                         'field1' => 'val01',
    *                                         'field2' => 'val02',
    *                                           ......
    *                                        ),
    *                            1 =>array(
    *                                         'field1' => 'val11',
    *                                         'field2' => 'val12',
    *                                           ......
    *                                        ),
    *                               ......
    *                       ),
    *
    *);
    *生成csv表样式为:
    *  字段1  字段2  字段3  字段4  ......
    *  val01  val02  val03  val04  ......
    *  val11  val12  val13  val14  ......
    *    .......
    */
    public function csvGenerator($content)
        {
    
    
            $str = '';//csv内容所保存的字符串
            foreach ($content['fields'] as $val) {
                $str .= ($val . ",");//设置表头 将表头依次设置为字段1、字段2...
    
            }
            $str .= "
    ";
            foreach ($content['data'] as $kkk => $row) {
                foreach ($content['fields'] as $k => $v) {
                    $row[$k] = str_replace('"', '""', $row[$k]);
                    $str .= ($row[$k] . ",");
                }
                $str = substr($str, 0, -1);//去掉每行最后一个逗号;
                $str .= "
    ";
            }
    
            return $str;
        }
    复制代码

    输出csv文件

    复制代码
    /**@param $filename
         * 输出csv文件的文件名
         * @param $data
         * 要写入csv文件的内容,即经过csvGenerator处理过的字符串;
         */
        public function csvExportWithBOM($filename='export.csv', $data)
        {
            $f=fopen("php://memory",'w');
            fwrite($f, chr(0xEF).chr(0xBB).chr(0xBF).$data);//加入BOM头
            fseek($f,0);
            header('Content-Type: application/csv');
            // 告知浏览器想要输出的是一个文件
            header('Content-Disposition: attachment; filename="'.$filename.'";');
            // make php send the generated csv lines to the browser
            fpassthru($f);
    
        }
    复制代码

    后记

    如果要导出的字段值中会出现",",那么务必在生成字符串的时候将英文逗号转为中文逗号,否则该字段值将被分到两个相邻的单元格,从而出现显示错误,另外,如果字段中出现了引号,那么请务必将引号如上例程序中的那样替换掉~

    谢谢您的耐心阅读~

  • 相关阅读:
    Activity具体解释(生命周期、以各种方式启动Activity、状态保存,全然退出等)
    StringBuffer和StringBuilder使用方法比較
    python 多线程编程
    八大排序算法总结
    腾讯面试
    顶尖的个人作品集站点设计赞赏
    MATLAB新手教程
    ThreadPoolExecutor使用介绍
    linux diff具体解释
    Android借助Application重写App的Crash(简易版)
  • 原文地址:https://www.cnblogs.com/yehuisir/p/11849876.html
Copyright © 2011-2022 走看看