Laravel DataTables 大型导出

Posted

技术标签:

【中文标题】Laravel DataTables 大型导出【英文标题】:Laravel DataTables large export 【发布时间】:2018-06-03 04:34:31 【问题描述】:

我已经接管了一个使用 Yajra DataTables 包的 Laravel 项目。该表呈现良好,我能够添加一个 CSV/Excel 导出按钮,该按钮在大多数情况下都可以正常工作。

我遇到的问题是我们的应用程序有时会输出 10k 条记录,当我尝试将完整的数据集导出到 CSV 时,它最终会在浏览器中产生一个空白页面并产生 500 内部服务器错误(空响应) 一段时间后。

我已经尝试更新所有 Laravel 和 Laravel DataTables 包,并尝试使用各种论坛帖子中的代码来尝试使用可能会分块处理的逻辑来覆盖包的 buildExcelFile(),但我总是得到相同的结果。

原始方法(source):

protected function buildExcelFile()

    /** @var \Maatwebsite\Excel\Excel $excel */
    $excel = app('excel');

    return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) 
        $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) 
            $sheet->fromArray($this->getDataForExport());
        );
    );

源使用另一个名为 laravel-excel 的包,但我不知道如何更新逻辑,以便它以更小的块处理并实际工作。

谁能帮助弄清楚使用 Yajra Laravel DataTables 包将大型结果集导出到 CSV 的逻辑?

【问题讨论】:

查看文档和源代码,chunk 选项似乎仅可用于导入:( 尝试将$this->getDataForExport() 放在外面并在每个闭包上使用它并通过它,它没有帮助它在关闭,因为它只会消耗内存。您可能需要考虑以不同的方式进行操作,因为当您有 20k 行时,它会继续中断。 谢谢@LawrenceCherone。我试图var_dump($this->getDataForExport()),即使这样也会产生相同的 500 服务器错误和空白响应。我什至尝试从包中深入研究这些方法,看看我是否能找出需要改进的地方,但经常卡住。甚至 getDataForExport 也有用于将 ajaxResponseData 映射到导出列的闭包,这只是一场噩梦。我以为我在其他项目的本地 DataTables 服务器端处理方面取得了成功,但我想在放弃它之前尝试解决 Laravel。 【参考方案1】:

我也遇到了这个问题,我使用以下步骤通过分块解决了这个问题: 我创建了一个名为 override 的类,它有一个方法可以覆盖默认的 buildExcelFile() 方法,并通过这个类扩展了我的所有数据表。这对我来说非常有效。这是我的覆盖类的代码

namespace App\DataTables;
use Maatwebsite\Excel\Classes\LaravelExcelWorksheet;
use Maatwebsite\Excel\Writers\LaravelExcelWriter;
use Yajra\Datatables\Services\DataTable;
class Override extends DataTable

protected function buildExcelFile()

/** @var \Maatwebsite\Excel\Excel $excel */
$excel = app('excel');

return $excel->create($this->getFilename(), function (LaravelExcelWriter    $excel) 
    $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) 
        $this->query()->chunk(100,function($modelInstance) use($sheet) 
        $modelAsArray = $modelInstance->toArray();
        foreach($modelAsArray as $model)
        $sheet->appendRow($model);
    );
  );
);public function query()

    // this method is overwritten in my datatable class , and it's that query result that is chunked method buildExcelFile() above
 

然后我的 Datatable 类看起来更像这样

<?php

namespace App\DataTables;
use ...
class AssignDataTable extends Override

...

希望对你有帮助。

【讨论】:

【参考方案2】:

如果有人使用 Laravel Excel 3.0+,上面的解决方案将不起作用。所以你应该使用“Queued Export”覆盖 buildExcelFile()。

或者我也通过使用分块做了其他事情,但通过创建我的特征并使用 CSV 来完成我的工作,这是我的 example。

【讨论】:

以上是关于Laravel DataTables 大型导出的主要内容,如果未能解决你的问题,请参考以下文章

基于数据表 Laravel 4 导出 CSV 或 PDF

Laravel DataTables HTML生成器插件

Laravel 4|5|6|7|8|9|10的jQuery DataTables API

数据表工具导出按钮不起作用

Laravel数据表按钮插件

yajra/laravel-datatables 搜索不适用于 laravel 5.4