【问题标题】:Export huge data into xlsx将海量数据导出到 xlsx
【发布时间】:2017-08-03 19:47:51
【问题描述】:

我需要使用 MISAM 引擎从 MySQL 数据库表中导出一个巨大的数据集到 Laravel 中的 .xlsx 文件中。

我正在使用基于PHPExcelmaatwebsite/laravel-excel 包。

数据包含大约 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

我可以做些什么来加快文件创建过程?只要我能达到相同的结果,我也愿意接受其他选择。

【问题讨论】:

  • PHP 不能做任何事情 + 这可能会占用大量内存,导出 CSV 并使用 Python 处理它,我敢打赌这将是 20-30 行代码......谷歌周围。哎呀,用 Python 做这一切,我是 PHP 人,但在这种情况下我会依赖 Python,因为它是一项长期运行的工作......
  • 为什么不坚持使用csv并在创建后将其转换为xlsx。这里有一些从 csv 转换为 xlsx 的资源 stackoverflow.com/questions/33815465/phpexcel-csv-to-xlsx phpclasses.org/browse/file/40495.html

标签: php laravel laravel-5 phpexcel laravel-excel


【解决方案1】:

我有 3 条建议:

  1. 使用cursor(尽管直到今天,我还没有发现它是否比块更好 - 也许你的案例可能会验证这一点) - 真诚地说,我只使用了这个和它的 Eloquent。

  2. 减小块的大小。我认为在内存中加载 15000 条记录已经是个问题了。

  3. 先创建excel文件,然后在工作表上使用rows()方法追加多行。 (这可能效果不佳,因为它需要一个数组)

【讨论】:

    猜你喜欢
    • 2015-12-17
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 2014-09-29
    相关资源
    最近更新 更多