Экспорт огромных данных в xlsx
Мне нужно экспортировать огромный набор данных из таблицы базы данных MySQL с движком MYISAM в .xlsx
файл в Laravel.
Я использую http://www.maatwebsite.nl/laravel-excel/docs/export, который основан на PHPExcel.
База данных содержит около 500 000 строк с 93 столбцами (около 46 500 000 ячеек) и довольно много вычислений, касающихся структуры заголовка.
Это код, который я сейчас использую:
// $excel_data contains some data regarding the project, nothing relevant here
$output = Excel::create('myproject-' . $excel_data->project->name . '-'.date('Y-m-d H:i:s') . '-export', function($excel) use($excel_data) {
// Set the title
$excel->setTitle($excel_data->project->name . ' Export');
$excel->sheet('Data', function($sheet) use($excel_data) {
$rowPointer = 1;
$query = DB::table('task_metas')
->where([
['project_id', '=', $excel_data->project->id],
['deleted_at', '=', null]
])
->orderBy('id');
$totalRecords = $query->count();
// my server can't handle a request that returns more than 20k rows so I am chunking the results in batches of 15000 to be on the safe side
$query->chunk(15000, function($taskmetas) use($sheet, &$rowPointer, $totalRecords) {
// Iterate over taskmetas
foreach ($taskmetas as $taskmeta) {
// other columns and header structure omitted for clarity
$sheet->setCellValue('A' . $rowPointer, $rowPointer);
$sheet->setCellValue('B' . $rowPointer, $taskmeta->id);
$sheet->setCellValue('C' . $rowPointer, $taskmeta->url);
// Move on to the next row
$rowPointer++;
}
// logging the progress of the export
activity()
->log("wrote taskmeta to row " . $rowPointer . "/" . $totalRecords);
unset($taskmetas);
});
});
});
$output->download('xlsx');
Согласно журналу, строки успешно записываются в файл, однако создание самого файла занимает много времени. Настолько долго, что он не завершает его за 1 час (это максимальное время выполнения этой функции).
Экспорт в CSV работает отлично, примерно через 10 минут он компилирует файл и загружает его, однако я не могу с этим работать - выходной файл должен быть xlsx
,
Что я могу сделать, чтобы ускорить процесс создания файла? Я также открыт для других альтернатив, пока я могу достичь тех же результатов.
1 ответ
У меня есть 3 предложения:
Используя курсор (хотя до сегодняшнего дня я не выяснил, лучше ли он, чем кусок - возможно, ваш случай мог бы это проверить) - С уважением, я использовал только этот и его с Eloquent.
уменьшить размер куска. Я думаю, что загрузка 15000 записей в память уже является проблемой.
Сначала создайте файл Excel, а затем используйте
rows()
метод на листе, чтобы добавить несколько строк. (это может не сработать, так как требует массив)