使用分页的方式,按偏移量来多次导出,追加合并为一个新文件,避免占用内存过高或下载过慢.
例子较简单:
<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<$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;
} //}}}
}
?>