使用分页的方式,按偏移量来多次导出,追加合并为一个新文件,避免占用内存过高或下载过慢.

例子较简单:

<pre>
<?php
class test extends Controller {
    private $table;
    private $file;
    private $filename;
    public function __construct(){
        parent::__construct();
        $this->file = FCPATH.'files/excel/';
        $this->filename = time().".csv";
    }
    function index($pid=null) { //{{{
        if(!$pid) exit("缺少id");
        $this->table = "project_{$pid}_search";
        $count = $this->db->from($this->table)->count_all_results();
        $basic = 300;
        $time = ceil($count/$basic);
        $t = 0;
        $start_time = microtime(true);
        for($i=0; $i&lt;$time; $i++){
            $start = $basic*$t++;
            self::section($start, $basic);
        }
        $end_time = microtime(true);
        echo '耗时'.round($end_time-$start_time,3).'秒';
        echo "<a href='/files/excel/{$this->filename}'>点击下载</a>";
    }   //}}}
    private function section($start, $limit){   //用分页的方式取出数据并写入文件{{{
        $sql = "select * from {$this->table} limit $start, $limit";
        $result = $this->db->query($sql)->result_array();
        $new_result = self::mapping($result);
        $file = $this->file.$this->filename;
        $open = fopen($file, 'a');  //以追加模式打开文件
        foreach($new_result as $r){
            fputcsv($open, $r);
        }
        fclose($open);
        $end = $start+$limit;
        echo "第 $start ~ $end 处理完成...<br />";
        ob_flush();
        flush();
    }   //}}}
    private function mapping($array){   //结果集转换成新的数组{{{
        $new_array = array();
        foreach ($array as $arr){
            $tmp_array = array();
            foreach($arr as $k){
                $tmp_array[] = $k;
            }
            $new_array[] = $tmp_array;
        }
        return $new_array;
    }   //}}}
}
?>