Laravel-datatables: 服务器端导出200000条记录

创建于 2018-03-31  ·  19评论  ·  资料来源: yajra/laravel-datatables

问题或功能要求摘要

当200000记录如何导出数据时。 当我导出数据“已耗尽134217728字节的允许的内存大小”时,抛出此异常。

还有什么其他方法可以导出yajra / datatable中的大量数据。

请提供另一种导出大量数据的方法。

我们在服务器上的内存数量有限。

问题的代码段

public function showData(ServiceDataTable $dataTable)
    {
        return $dataTable
            ->render('dataTable.renderDataTable');
    }

系统详情

  • 作业系统:Ubuntu 16.04
  • PHP版本:7.0.0
  • Laravel版本:5.5
  • Laravel-Datatables版本:8.0
  • Laravel-Datatables按钮版本:3.1
performance question

所有19条评论

您需要实现自己的excel文件生成器来处理此批量请求。 在ServiceDataTable类上,您可以重写protected function buildExcelFile()方法,并可以做一些大块工作,等等。有关更多信息,请参见laravel-excel文档。

    /**
     * Build excel file and prepare for export.
     *
     * <strong i="7">@return</strong> \Maatwebsite\Excel\Writers\LaravelExcelWriter
     */
    protected function buildExcelFile()
    {
        /** <strong i="8">@var</strong> \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());
            });
        });
    }

我认为以下代码创建异常
$this->getDataForExport();
定义或使用服务器端editColumn()时获取异常
有200000条记录。
还有其他方法可以获取数据而不进行处理或不分配更多的内存。
我有以下链接,但yajra yajra / laravel-datatables-buttons:^ 3.1尚不支持Laravel / Excel:3.0
https://laravel-excel.maatwebsite.nl/docs/3.0/export/queued

应该有一种直接从查询导出或雄辩的方式。

我使用邮递员来模仿该操作,但是

允许的内存大小为134217728字节已用尽

引发异常。 我没有用于生成html的行,我使用rawColumns()来转义html,我的查询在phpmyadmin中花了0.420毫秒,在开始的1.4秒钟中。

如果我们能够将其放入队列,我们​​还应该能够将其保存到服务器上的文件夹中,然后提供链接以供用户下载。

感谢您的回应。

我在JQuery Datatable或yajra datatable中使用它,并希望从服务器端导出。

我认为将其保存到服务器上的文件夹中是不可行的,会有很多问题会产生问题。

我需要流数据。

响应的数据量为20MB或更大。

我的要求与此类似,但我想将文件保存到服务器(或S3)上,并提供一个链接,以将其下载到应用程序仪表板或电子邮件中。 我发现这样做的可能性,如果我发现有什么要更新的话。

我在服务器端处理过程中遇到问题,该过程消耗大量的ram,默认脚本内存分配大小为60MB。
查看php.ini中的memory_limit
执行时间限制max_execution_time是60。
增加价值之后,您就可以使用服务器端导出进行请求。

我修改了excel函数来存储文件而不是下载文件,它是将文件存储在storage / exports /文件夹中。

public function excel()
{
    $this->buildExcelFile()->store('xls');
}

当前我的开发环境中没有大量数据,您可以在设置中进行上述更改,看看它是否能够在不破坏存储容量的情况下在该文件夹中创建Excel吗?

要注意的另一件事是我正在使用Laravel 5.1,因此maatwebsite / excel版本2.1

我真正想做的是将其放在队列中,然后返回页面,并显示一条消息,报告正在创建中,下载文件的链接将通过电子邮件发送到您注册的ID。

在2.1版本中,不确定如何排队,但是我在他们使用“ Queued Chunk ”的地方发现了这个,但是我不确定如何实现。

那么对此有任何更新吗?

那么对此有任何更新吗?

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

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

任何更新 ?

从Laravel 6开始,您可以使用LazyCollections一次仅在内存中加载一项。 这解决了内存不足的问题。

只需要扩展DataTable类并编写一个适应的DataTablesExportHandler。

看看我的要点

享受!

@singhofmarco能举个例子吗?

@singhofmarco我同意,去年已经启动了一个v10项目,该

我走了一条不同的路线。 我重写了csv函数,每次用一页数据调用DataTables,有效地进行了分块。 在结果行上使用fputcsv直到文件完成,然后在Laravel Response中返回文件内容。

不仅不再达到内存限制(直到CSV本身超过PHP内存限制,然后流式响应可能会进一步提供帮助),而且速度也提高了两倍以上……

@ameenross,如果可以的话,请您分享您的代码。

@karmendra我不想,因为它是针对Yajra Datatables的较旧版本。 但是基本上我在做的是在请求中合并一些page&length值,调用通常返回AJAX数据页面的代码(本例中$this->ajax()->getData(true)['data'] )。 我有一个数据表的基类,它扩展了Yajra Datatable类,并带有一个函数getCsv (决定毕竟不覆盖CSV函数,但这并不重要)。 这会一直循环,直到没有剩余的页面为止。

@ameenross谢谢您的帮助。 我将尝试一下。

Laravel数据表:: v1.5.0
这是基于@TheGeekyM评论的我的解决方案,如果有帮助,我会保留它。
我创建了一个ChunkedDatatableExportHandler类,该类实现FromQuery,然后在ServiceDataTables中覆盖buildExcelFile方法以使用它。

<?php

namespace App\DataTables;

use Yajra\DataTables\Services\DataTable;

class ServiceDataTable extends DataTable
{
  protected $exportClass = ChunkedDatatableExportHandler::class;

  protected function buildExcelFile()
  {
      $query = app()->call([$this, 'query']);
      $query = $this->applyScopes($query);

      $dataTable = app()->call([$this, 'dataTable'], compact('query'));
      $dataTable->skipPaging();
      $data_query = $dataTable->getFilteredQuery();

      return new $this->exportClass($data_query);
  }
}
<?php
namespace App\DataTables;

use Illuminate\Database\Query\Builder;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;

class ChunkedDatatableExportHandler implements FromQuery, WithHeadings
{
    use Exportable;

    /**
     * <strong i="11">@var</strong> Builder 
     */
    protected $query;

    /**
     * ChunkDatatablesExportHandler constructor.
     * <strong i="12">@param</strong> Builder $query
     */
    public function __construct(Builder $query)
    {
        $this->query = $query;
    }

    /**
     * <strong i="13">@return</strong> array
     */
    public function headings(): array
    {
        $first = $this->query()->first();

        if ($first) {
            return array_keys((array)$first);
        }

        return [];
    }

    /**
     * <strong i="14">@return</strong> Builder
     */
    public function query()
    {
        return $this->query;
    }
}
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

jgatringer picture jgatringer  ·  3评论

josiahke picture josiahke  ·  3评论

techguydev picture techguydev  ·  3评论

macnux picture macnux  ·  3评论

t0n1zz picture t0n1zz  ·  3评论