把数组处理成csv文件,并压缩成zip文件下载
zipfile('xxx.zip');
function zipfile($zipname) {
$headers = ['1', '2', '3', '4'];
$zip = new ZipArchive();
$zip->open($zipname, ZipArchive::CREATE);
// loop to create 3 csv files
for ($i = 1; $i < 4; $i++) {
$records = getRecord($i);
$fd = putfile($zip, $headers, $records);
// add the in-memory file to the archive, giving a name
$zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd));
//close the file
fclose($fd);
}
// close the archive
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
// remove the zip archive
// you could also use the temp file method above for this.
unlink($zipname);
}
function getRecord($i) {
$records1 = [
['111', '222', '333', '111'],
['111', '222', '333', '111'],
['111', '222', '333', '111'],
['111', '222', '333', '111'],
['111', '222', '333', '111'],
['111', '222', '333', '111'],
];
$records2 = [
['111', '222', '333', '222'],
['111', '222', '333', '222'],
['111', '222', '333', '222'],
['111', '222', '333', '222'],
['111', '222', '333', '222'],
['111', '222', '333', '222'],
];
$records3 = [
['111', '222', '333', '333'],
['111', '222', '333', '333'],
['111', '222', '333', '333'],
['111', '222', '333', '333'],
['111', '222', '333', '333'],
['111', '222', '333', '333'],
];
$name = 'records' . $i;
return $$name;
}
function putfile($zip, $headers, $records) {
// create a temporary file
$fd = fopen('php://temp/maxmemory:1048576', 'w');
if (false === $fd) {
die('Failed to create temporary file');
}
// write the data to csv
fputcsv($fd, $headers);
foreach($records as $record) {
fputcsv($fd, $record);
}
// return to the start of the stream
rewind($fd);
return $fd;
}
直接输出csv文件 utf-8格式
function outputCsv($content) {
$filename = 'xxx' . '_' . date('Ymd') . 'csv';
header("Content-Disposition:attachment;filename=" . $filename);
header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
header('Expires:0');
header('Pragma:public');
header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
echo $content;
整理一个包含csv头的数组导出成csv文件
public static function exportCsv($data)
{
if (count($data) === 0) {
return '';
}
$file = fopen('php://memory', 'wb');
$header = $data[0];
$header_name = array_keys($header);
$header_name_index = array_flip($header_name);
$header_size = count($header);
foreach ($data as $row) {
$converted_row = [];
for ($i = 0; $i < $header_size; $i++) {
$converted_row[] = '';
}
foreach ($row as $key => $cell) {
$index = -1;
if (is_int($key) && $key >= 0 && $key < $header_size) {
$index = $key;
} elseif (isset($header_name_index[$key])) {
$index = $header_name_index[$key];
}
if ($index >= 0) {
$converted_row[$index] = $cell;
}
}
unset($key, $cell);
ksort($converted_row, SORT_NUMERIC);
fputcsv($file, $converted_row);
}
unset($row);
fseek($file, 0, SEEK_SET);
$content = '';
$buffer_size = 8192;
while (feof($file) === false) {
$content .= fread($file, $buffer_size);
}
fclose($file);
return $content;
}
//输出csv文件,点击链接自动下载
outputCsv(self::exportCsv($data));
没法通过一次请求导出多个csv文件,只能通过zip打包多个csv文件,一次性下载。
大文件因为打开文件写入时间比较长,很容易timeout。
可以修改, 有一些作用。
nginx.conf
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
php-fpm
request_terminate_timeout = 60s
网友评论