代码之家  ›  专栏  ›  技术社区  ›  PeterInvincible

将大量数据导出到xlsx

  •  3
  • PeterInvincible  · 技术社区  · 7 年前

    我需要使用MYISAM引擎将MySQL数据库表中的一个巨大数据集导出到 .xlsx 在Laravel归档。

    maatwebsite/laravel-excel PHPExcel

    数据集包含约500000行93列(约46500000个单元格),以及许多关于标头结构的计算。

    这是我目前使用的代码:

    // $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 回复  |  直到 7 年前
        1
  •  0
  •   Oluwatobi Samuel Omisakin    7 年前

    我有3条建议:

    1. 使用 cursor

    2. 首先创建excel文件,然后使用 rows()