要点一:
对于导出大量数据不能使用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;
}