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

爨习
• 阅读 4100

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

  1. 导出为excel

  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"

或者

$strId."\n"

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

$strId." "

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

set_time_limit(60*5);

3.默认内存设置太小,导致文件写入失败:
可以尝试这样解决

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

4.奇淫技巧
如果不想文件在读取或者写入的时候,因为用户的误操作被中断。可以通过如下参数实现:

ignore_user_abort(true);

以上是我自己在多次管理后台开发实现导出功能时曾经遇到过的问题,主页菌在此列出来希望可以和大家一起探讨一下。

点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
vue+iview中的table表格导出excel表格
一、iveiw框架中table中有exportCsv()方法可以导出.csv后缀文件,类似于excel文件,但是并不是excel文件。二、实现table表格导出excel文件利用Blob.js和Export2Excel.js两个文件实现  1.Blob.js和Export2Excel.js文件    链接:https://pan.baid
Wesley13 Wesley13
3年前
java实现接口导出csv文件
<palign"center"<imgsrc"http://qiniu.tomxin.cn/blog/180920/5BkJdmB10j.png?imageslim"alt"MaterialRenderPhone"</p<h1align"center"<ahref"http://tomxin.cn"target"\
Stella981 Stella981
3年前
ASMSupport教程4.8 生成逻辑运算操作
<p在java中有以下逻辑运算符:</p<ul<li&amp;&amp;:条件与</li<li||:条件或</li<li&amp;:布尔型的逻辑与</li<li|:布尔型的逻辑或</li<li^:布尔型的逻辑异或</li<li!:非操作</li</ul<p那么接下来我们将些段例子
Stella981 Stella981
3年前
Python之CSV模块
1\.CSV简介CSV(CommaSeparatedValues)是逗号分隔符文本格式,常用于Excel和数据库的导入和导出,Python标准库的CSV模块提供了读取和写入CSV格式文件的对象。1.1csv.reader对象和csv文件的读取
Wesley13 Wesley13
3年前
Oracle 19c sqlplus 新的系统变量
新版本的sqlplus可以导出结果为csv格式了,此前只有html格式选项。如果你想仅仅导出数据结果为csv文件,还有其他的系统变量你需要注意的。SETECHOOFF关闭命令自身显示SETTERMOUNTOFF关闭命令输出显示SETFEEDBACKOFF关闭记录数返回SETV
Wesley13 Wesley13
3年前
mysql 5.7 windows zip安装
<ol<limysql官网下载windowszip安装包并解压(D:wampmysql56winx64)</li<li添加pathD:wampmysql5722winx64bin</li<li创建data目录D:\\wamp\\mysql56winx64\\data</li<li<p创建mysql配置文
Stella981 Stella981
3年前
ASMSupport教程4.11 生成数组操作
<p在任何语言里,数组都是基本的数据类型,我们这一节将讲述如何生成数组操作。</p<p数组操作包括以下几个:</p<ol<li创建数组</li<li获取数组长度</li<li获取数组每个元素的内容</li<li为数组元素赋值</li</ol<p我们接下来对每种操作进行详解。</p<h3<fonts
Stella981 Stella981
3年前
ASMSupport教程4.12 生成方法调用操作
<p这一节我们讲如何用ASMSupport生成方法调用的操作,方法调用包括下面四种类型:</p<ol<li调用构造方法<li调用静态方法<li调用非静态方法<li调用当前类的方法<li调用父类方法</li</ol<p首先我们需要看我们想要生成的类:</p<p代码1:</p<h3<divid"scid:9D
Wesley13 Wesley13
3年前
HTML快捷写法大全
父子用\ \Ulli\3\<ul\    <li\</li\    <li\</li\    <li\</li\</ul\兄弟之间用,也可以省写\pspan\,\ul\<p\</p\<span
流浪剑客 流浪剑客
1年前
网络爬虫开发工具:Screaming Frog SEO Spider for Mac 最新中文版 支持M1 附注册码
是一款功能强大的SEO工具,可以帮助用户进行网站的SEO优化和分析。以下是ScreamingFrogSEOSpider的主要特点:网站爬取:可以快速扫描整个网站并列出所有内部和外部页面,包括URL,标题,描述和头信息等。数据导出:可以将扫描结果导出为CSV
流浪剑客 流浪剑客
1年前
「最新更新」Screaming Frog SEO Spider for Mac 网络爬虫开发工具
是一款功能强大的SEO工具,可以帮助用户进行网站的SEO优化和分析。以下是ScreamingFrogSEOSpider的主要特点:网站爬取:可以快速扫描整个网站并列出所有内部和外部页面,包括URL,标题,描述和头信息等。数据导出:可以将扫描结果导出为CSV