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