当200000记录如何导出数据时。 当我导出数据“已耗尽134217728字节的允许的内存大小”时,抛出此异常。
还有什么其他方法可以导出yajra / datatable中的大量数据。
请提供另一种导出大量数据的方法。
我们在服务器上的内存数量有限。
public function showData(ServiceDataTable $dataTable)
{
return $dataTable
->render('dataTable.renderDataTable');
}
您需要实现自己的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;
}
}