关于PHP导出CSV文件的实现过程以及一些常常遇到的问题研究

导出功能在管理后台算是比较常见的了。在实现导出表格类信息的功能时,能够选择两种实现方式:php

  1. 导出为excelapi

  2. 导出为csv文件格式数组

用csv方式导出,则能够像导出txt同样,以文本流的方式进行流式处理,不但能导出海量信息,并且流式处理占用内存极低,服务器对浏览器的响应也是很是迅速的。理论上是不限量的。具体能导出多少条,是由服务器的响应时间、PHP的运行时间和内存等限制决定。可是若是用excel来打开csv,超过65536行的数据都会看不见,这是excel程序的问题。本次导出数据量很大。因此选择csv。
整体实现思路为:
先把须要导出的数据存到数组里,而后写入到文件。话很少说,仍是直接上代码吧。浏览器

function export(){
    $data=array(
       array(
         'nId' => '90',
         'nick' => 'piapia',
       ),
       array(
         'nId' => '91',
         'nick' => 'monkey',
       )
     );
      $head = array(
         'nId' => 'id',
         'nick' => '昵称',
    );
    
    $name = "filetoexport" . date('YmdHis', time());
    $this->writeCsvToBrowser($name, $head, $data);

}

function writeCsvToBrowser($filename,$headLine,$data,$lostData=array()) {
    $out    =    implode(',', $headLine);
    $out    =    iconv('UTF-8', 'GBK//IGNORE',$out);
    
    foreach ($data as $v) {
        $line    =    array();
        foreach (array_keys($headLine) as $objAttr) {
            if (is_object($v) && isset($v->$objAttr)) {
                $cellValue    =    $v->$objAttr;
            }elseif(is_array($v) && isset($v[$objAttr])) {
                $cellValue    =    $v[$objAttr];
            }else {
                $cellValue    =    $lostData[$objAttr];
            }
            $line[]    =    $cellValue;
        }
        $line = array_map('csvFormate',$line);
        $out    .=    "\n";
        $lineStr=    implode(',', $line);
        //iconv转换编码对字符串有长度限制,若是太长就会被截断。
        $lineStr=    @iconv('UTF-8', 'GBK//IGNORE', $lineStr);
        $out    .=    $lineStr;
    }
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Content-Length: " . strlen($out));
    header("Content-type: text/x-csv");
    header("Content-Disposition:filename=$filename.csv");
    echo $out;
}


function csvFormate($str) {
    if (''===$str) {
        return '';
    }
    $find = FALSE;
    foreach (array(',','"',"\n","\t") as $v){
        if (FALSE===strpos($str, $v)) {
            $find = true;
            break;
        }
    }
    if (!$find) {
        return $str;
    }
    $str    =    str_replace('"', '""', $str);
    return sprintf('"%s"',$str);
}

在实现这个功能时,有一些问题须要你们注意一下。
1.精度丢失问题:
问题描述:导出后,发现有一个字段老是跟取得不同,Id为1918553121332457在导出后变成1918553121332450,也就是说最后一位 老是变成了0。
缘由:Excel数值显示精度为15位形成精度丢失。
解决思路:强制转化成字符串服务器

$strId."\t"

或者post

$strId."\n"

须要注意的是,这样加是没有用的:this

$strId." "

2.PHP运行时间的限制,致使程序被强制中断。
在不能随便改变php.ini文件里PHP运行的时间限制下,能够这样设置来增长运行时间:编码

set_time_limit(60*5);

3.默认内存设置过小,致使文件写入失败:
能够尝试这样解决excel

ini_set('memory_limit','1024M');

4.奇淫技巧
若是不想文件在读取或者写入的时候,由于用户的误操做被中断。能够经过以下参数实现:code

ignore_user_abort(true);

以上是我本身在屡次管理后台开发实现导出功能时曾经遇到过的问题,主页菌在此列出来但愿能够和你们一块儿探讨一下。

相关文章
相关标签/搜索