要点一:
对于导出大量数据不能使用Excel,会导致输出数据不全。
Excel2003限制为65536行就Excel2007限制为1048576行
对于CSV目前对数据量没有限制,所以大量数据导出选用。
要点二:
PHP处理大数据导出时,要强行刷出缓存在服务器和WEB浏览器中的缓存,避免爆内存。
使用的函数:ob_flush() flush()同时使用才会奏效。
生成EXCEL的三张方法:
excel:[\t \n]
csv: [, \n]
csv: [fputcsv] PHP函数
1.导出EXCEL:
主要使用声明头文件、输出格式使用[\t \n]
//导出Excel:单元格'\t'分隔,换行\n header("Content-type:application/vnd.ms-excel"); header("Content-Disposition:filename=excel.xls"); echo "A1\t B1\t C1\n"; echo "A2\t B2\t C2\n"; echo "A3\t B3\t c3\n";
2.导出CSV
主要使用声明头文件、输出格式使用[ , \n]
//导出CSV:单元格','分隔,换行\n header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename=csv.csv'); header('Cache-Control: max-age=0'); echo "A1, B1, C1\n"; echo "A2, B2, C2\n"; echo "A3, B3, c3\n";
3.导出大量数据:
百万以上的实现如下(注意不要一次获取mysql大量数据,可以去ID再去生成CSV,在循环去库中拿数据)fputcsv
set_time_limit(0); error_reporting(0); // 输出Excel文件头,可把user.csv换成你要的文件名 header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="user.csv"'); header('Cache-Control: max-age=0'); $fp = fopen('/tmp/export/data.csv', 'a'); $head = array('UID', 'EMAIL', '注册时间', '第一次登陆时间'); foreach ($head as $i => $v) { // CSV的Excel支持GBK编码,一定要转换,否则乱码 $head[$i] = iconv('utf-8', 'gbk', $v); } fputcsv($fp, $head); $result = array(.................................); foreach($resutl as $val){ ob_flush(); flush(); // 从数据库中获取数据,为了节省内存,不要把数据一次性读到内存,从句柄中一行一行读即可 $sql = "SELECT uid,email,regdate,lastlogintime FROM reg_members WHERE email in ($val) ORDER BY uid ASC, regdate ASC"; $query = $db_reg_read -> query($sql); while ($res = $db_reg_read -> fetch_array($query)) { $email = strtolower($res['email']); $list[] = $res; } //对数据进行整理 //输入到CSV中 foreach($list as $key => $val){ $row[0] = iconv('utf-8', 'gbk', $val['uid']); $row[1] = iconv('utf-8', 'gbk', $val['email']); $row[2] = iconv('utf-8', 'gbk', $val['regdate']); $row[3] = iconv('utf-8', 'gbk', $val['lastlogintime']); fputcsv($fp, $row); } }
PHP导入导出csv文件的案例
以下列举一些实际项目中的代码来说明csv的导入导出:
导入Excel
/** * 导入目标数据 * @param string $tmp_filename 临时文件地址 */ public function importTargetData() { ignore_user_abort(); @ini_set('max_execution_time', '300'); try { $fileName = $this->checkCsvFile(); $common = new Common(); $totalLines = $common->getFileLineNumber($fileName); if ($totalLines < 2) { throw new \Exception('文件是空的'); } if ($totalLines >= 10000) { throw new \Exception('行数太多,不能接受'); } // 清理中间库 MmAchievementShop::onWriteConnection()->whereIn('availability', [0, 1, 2, 3])->delete(); // 步长 $num = 150; // 行数 $s = 2; for ($i = 2; $i <= $totalLines; $i += $num) { // 完善字段 $data = []; $csvData = $common->getCsvLines($fileName, $i, $i + $num - 1); // 处理数据 foreach ($csvData as $line => $v) { // 处理字段进行操作 if (empty($v[0]) || empty($v[1]) || empty($v[2]) || empty($v[3])) { if (empty($v[0]) && empty($v[1]) && empty($v[2]) && empty($v[3])) { // 完全就是个空行 continue; } else { throw new \Exception('存在残缺表数据[' . $s . ']'); } } } unset($csvData); $s++; } return true; } catch (\Exception $e) { return $e->getMessage(); } }
导出Excel
一个下载csv文件模板的程序例子
public function makeCsvTemplate() { @ini_set('memory_limit', '400M'); @ini_set('max_execution_time', '0'); $filename = '目标与完成度' . date('YmdHis') . '.csv'; header("Content-type:text/csv"); header("Content-Disposition:attachment;filename=" . $filename); header('Cache-Control: max-age=0'); $fp = fopen('php://output', 'a'); // csv的列名 $i = 0; $contentArr = []; $headerList = Config('c2bData.targetColumnName'); foreach ($headerList as $v) { $v = str_replace(array( "\r\n", "\r", "\n", ), '', $v); $contentArr[$i] = iconv('utf-8', 'gbk//IGNORE', $v); $i++; } fputcsv($fp, $contentArr); $contentList = []; // 查询对象 $contentList[] = $this->formatExportStr('全国'); // 月份 $contentList[] = $this->formatExportStr('2017#01'); // 线索转化率目标值 $contentList[] = $this->formatExportStr('0.10%'); // 门店-单车利润目标值 $contentList[] = $this->formatExportStr('2000'); fputcsv($fp, $contentList); $currentDate = date('Ym', time()); $sampleList = BiC2bTarget::whereIn('query_type', [2, 3, 4]) ->where('date_month', $currentDate) ->orderBy('query_type', 'asc') ->lists('object_name')->toArray(); $countOfList = count($sampleList); for ($i = 0; $i < $countOfList; ++$i) { $contentList = []; // 查询对象 $contentList[] = $this->formatExportStr($sampleList[$i]); // 月份 $contentList[] = ''; // 线索转化率目标值 $contentList[] = ''; // 门店-单车利润目标值 $contentList[] = ''; fputcsv($fp, $contentList); } }
导出的例子
/** * 导出 * 鬼知道数据库里都是什么格式的数据,为了防止导出乱码,一律使用了formatExportStr进行转码 */ public function exportAchievementData($request) { @ini_set('memory_limit', '400M'); @ini_set('max_execution_time', '0'); $filename = '目标与完成度' . date('YmdHis') . '.csv'; header("Content-type:text/csv"); header("Content-Disposition:attachment;filename=" . $filename); header('Cache-Control: max-age=0'); $fp = fopen('php://output', 'a'); // csv的列名 $i = 0; $contentArr = []; $headerList = Config('c2bData.exportAchiList'); foreach ($headerList as $v) { $v = str_replace(array( "\r\n", "\r", "\n", ), '', $v); $contentArr[$i] = iconv('utf-8', 'gbk//IGNORE', $v); $i++; } fputcsv($fp, $contentArr); unset($contentArr, $headerList); $objArr = $this->getDataBySearcher($request); foreach ($objArr as $v) { $contentList = []; // 查询对象 $contentList[] = $this->formatExportStr($v['object_name']); $v['date_month'] = $this->formatMonthData((string) $v['date_month']); // 月份 $contentList[] = $this->formatExportStr($v['date_month']); // 线索转化率目标值 $contentList[] = $this->formatExportStr($v['target_clue']); // 线索实际值 $contentList[] = $this->formatExportStr($v['actual_clue']); // 线索完成度 $contentList[] = $this->formatExportStr($v['complete_clue']); // 门店-单车利润目标值 $contentList[] = $this->formatExportStr($v['target_profit']); // 门店实际值 $contentList[] = $this->formatExportStr($v['actual_profit']); // 门店完成度 $contentList[] = $this->formatExportStr($v['complete_profit']); // 线索量(条) $contentList[] = $this->formatExportStr($v['clue']); // 计划收购量 $contentList[] = $this->formatExportStr($v['target_buy']); // 实际收购量 $contentList[] = $this->formatExportStr($v['buy']); // 收购差异(台) $contentList[] = $this->formatExportStr($v['diff_buy']); fputcsv($fp, $contentList); } }
过滤并转码的例子
/** * 过滤并转码导出至csv的数据 * @param string $str * @return string $str */ public function formatExportStr($str) { if (!empty($str)) { $str = iconv('utf-8', 'gbk//IGNORE', str_replace(array( "\r\n", "\r", "\n", ), '', $str)); } return $str; }