/**
* 重写fputcsv方法,添加转码功能
* @param $handle
* @param array $fields
* @param string $delimiter
* @param string $enclosure
* @param string $escape_char
*/
function fputcsv2($handle, array $fields, $delimiter = ",", $enclosure = '"', $escape_char = "\") {
foreach ($fields as $k => $v) {
$fields[$k] = iconv("UTF-8", "GB2312//IGNORE", $v); // 这里将UTF-8转为GB2312编码
}
fputcsv($handle, $fields, $delimiter, $enclosure, $escape_char);
}
/**
* 导出csv
*/
public function csv()
{
set_time_limit(0);
ini_set('memory_limit', '128M');//设置文件最大限制
$fileName = date('YmdHis', time());//文件名
// 设置头部
header('Content-Encoding: UTF-8');
header("Content-type:application/vnd.ms-excel;charset=UTF-8");
header('Content-Disposition: attachment;filename="' . $fileName . '.csv"');
//注意,数据量在大的情况下。比如导出几十万到几百万,
//会出现504 Gateway Time-out,请修改php.ini的max_execution_time参数
//打开php标准输出流以写入追加的方式打开
$fp = fopen('php://output', 'a');
//设置标题
$title = array('id', '编号', '姓名', '年龄');
//注意这里是小写id,否则ID命名打开会提示Excel 已经检测到"xxx.xsl"是SYLK文件,但是不能将其加载: CSV 文或者XLS文件的前两个字符是大写字母"I","D"时,会发生此问题。
foreach ($title as $key => $item){
$title[$key] = iconv("UTF-8", "GB2312//IGNORE", $item);
}
fputcsv2($fp, $title);
// 导出百万级别数据时才需要用到for循环
//用fputcsv从数据库中导出1百万的数据,比如我们每次取1万条数据,分100步来执行
//一次性读取1万条数据,也可以把$nums调小,$step相应增大。
//$step = 100;
//$nums = 10000;
// for ($s = 1; $s <= $step; $s++) {
// $start = ($s - 1) * $nums;
$result = M()->query("SELECT id,username,logtime,gid FROM admin");
foreach($result as $key=>$row){
foreach ($row as $key => $item){
$row[$key] = iconv("UTF-8", "GBK", $item); //这里必须转码,不然会乱码
}
fputcsv($fp, $row);
}
//ob_flush(); //每1万条数据就刷新缓冲区
//flush();
// }
}