Когда 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
Должен быть способ, который напрямую экспортирует из запроса или красноречиво.
Я использую Postman, чтобы имитировать эту операцию, но
Допустимый объем памяти 134217728 байт исчерпан
выброшено исключение. У меня нет строк, которые использовались для генерации html, я использую rawColumns () для выхода из html, мой запрос занимает 0,420 мс в phpmyadmin и сначала 1,4 секунды.
Если мы сможем поместить это в очередь, мы также сможем сохранить его в папке на сервере, а затем предоставить пользователю ссылку для его загрузки.
Спасибо за ответ.
Я использую его в JQuery Datatable или yajra datatable и хочу экспортировать со стороны сервера.
Я думаю, что невозможно сохранить в папку на сервере, есть много проблем, которые могут вызвать проблемы.
Мне нужна потоковая передача данных.
Размер ответных данных составляет 20 МБ или больше.
Мое требование аналогично, но я хотел бы сохранить файл на сервере (или S3) и дать ссылку для его загрузки на панели инструментов моего приложения или по электронной почте. Я вижу возможность сделать это, если найду что-нибудь, я обновлю здесь.
У меня проблема с обработкой на стороне сервера, которая потребляет большое количество оперативной памяти, а размер выделения памяти сценария по умолчанию составляет 60 МБ.
Посмотрите memory_limit в php.ini
Лимит времени выполнения max_execution_time
составляет 60.
После увеличения значения вы смогли сделать запрос, используя экспорт на стороне сервера.
Я изменил функцию Excel, чтобы сохранить файл вместо загрузки, он хранит файл в папке storage / exports /.
public function excel()
{
$this->buildExcelFile()->store('xls');
}
в настоящее время у меня нет большого количества данных в моем окружении разработки, можете ли вы внести указанные выше изменения в свою настройку и посмотреть, сможет ли он создать Excel в этой папке, не затрагивая ограничение памяти?
Также следует отметить, что я использую Laravel 5.1, поэтому maatwebsite / excel версии 2.1
Что я действительно хочу сделать, так это поставить его в очередь и вернуться на страницу с сообщением о том, что отчет создается, а ссылка для загрузки файла будет отправлена по электронной почте на ваш зарегистрированный идентификатор "
в версии 2.1 не знаю, как поставить в очередь, но я обнаружил, что здесь используется « Queued Chunk », но я не уверен, как это реализовать.
Есть новости по этому поводу?
Есть новости по этому поводу?
Если кто-то использует Laravel Excel 3.0+, верхнее решение работать не будет. поэтому вы должны переопределить buildExcelFile()
, используя «Экспорт в очереди» .
Или я сделал что-то еще, используя также фрагменты, но создав свой трейт и используя CSV для выполнения своей работы, и это пример
любые обновления ?
Начиная с Laravel 6, вы можете использовать LazyCollections для загрузки в память только одного элемента за раз. Это решает проблему нехватки памяти.
Нужно только расширить класс DataTable и написать адаптированный DataTablesExportHandler.
Наслаждайтесь!
@singhofmarco Можете подать пример?
@singhofmarco Я согласен, в прошлом году я начал проект v10, который будет использовать LazyCollections, но не может продолжать его.
Я пошел другим путем. Я переопределил функцию csv, каждый раз вызывая DataTables с одной страницей данных, эффективно разбивая их на части. Используя fputcsv
в строках результатов до тех пор, пока файл не будет завершен, просто верните содержимое файла в ответе Laravel.
Мало того, что предел памяти больше никогда не достигается (пока сам CSV не превысит предел памяти PHP, тогда потоковый ответ может помочь в дальнейшем), но он также более чем в два раза быстрее ...
@ameenross, если возможно, поделитесь своим кодом, пожалуйста.
@karmendra Я бы не стал, так как это для более старой версии Yajra Datatables. Но в основном то, что я делаю, это объединяю некоторые значения страницы и длины в запросе, вызываю код, который обычно возвращает страницу данных для AJAX (в моем случае $this->ajax()->getData(true)['data']
). У меня есть базовый класс для таблиц данных, который расширяет класс Yajra Datatable с функцией getCsv
(в конце концов, решил не переопределять функцию CSV, но это не важно). Это продолжается до тех пор, пока не закончатся страницы.
@ameenross Спасибо, что помогло. Я попробую.
Laravel Datatable :: v1.5.0
Вот мое решение, основанное на комментарии @TheGeekyM , я оставляю его на случай, если это поможет кому-то другому.
Я создал класс ChunkedDatatableExportHandler, который реализует FromQuery, а затем переопределил метод buildExcelFile в моих таблицах ServiceDataTables, чтобы использовать его.
<?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;
}
}