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);
    
        }
    复制代码

    后记

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

    谢谢您的耐心阅读~

  • 相关阅读:
    Zend Framework 2.1.5 中根据服务器的环境配置调用数据库等的不同配置
    在基于 Eclipse 的 IDE 中安装和使用 Emmet(ZenCoding)
    【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet
    【翻译】Emmet(Zen Coding)官方文档 之二 缩写
    【翻译】Emmet(Zen Coding)官方文档 之七 一览表
    【翻译】Emmet(Zen Coding)官方文档 之三 CSS 缩写
    【翻译】Emmet(Zen Coding)官方文档 之四 动作
    【翻译】Emmet(Zen Coding)官方文档 之一 web 编程的必备工具
    Zend Framework 2 时区设置警告问题的解决
    【翻译】Emmet (Zen Coding) 元素类型
  • 原文地址:https://www.cnblogs.com/yehuisir/p/11849876.html
Copyright © 2011-2022 走看看