要點一:
對於導出大量數據不能使用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; }