Laravel-datatables: تصدير جانب الخادم 200000 سجلات

تم إنشاؤها على ٣١ مارس ٢٠١٨  ·  19تعليقات  ·  مصدر: yajra/laravel-datatables

ملخص المشكلة أو طلب الميزة

عندما يسجل 200000 كيفية تصدير البيانات. عندما أقوم بتصدير البيانات "استنفاد حجم الذاكرة المسموح بها 134217728 بايت" هذا الاستثناء.

ما هي الخيارات الأخرى لتصدير كمية كبيرة من البيانات في yajra / datatable.

يرجى تقديم طريقة مختلفة لتصدير كمية كبيرة من البيانات.

لدينا كمية محدودة من ذاكرة الوصول العشوائي على الخادم.

مقتطف رمز المشكلة

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

تفاصيل النظام

  • نظام التشغيل: أوبونتو 16.04
  • إصدار PHP: 7.0.0
  • إصدار Laravel: 5.5.2
  • إصدار Laravel-Datatables: 8.0.2
  • إصدار أزرار Laravel-Datatables: 3.1.2
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-: ^ 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 datable وأريد التصدير من جانب الخادم.

أعتقد أنه ليس من الممكن الحفظ في مجلد على الخادم ، فهناك العديد من المشكلات التي ستؤدي إلى حدوث مشكلة.

أحتاج إلى تدفق البيانات.

حجم البيانات بحجم 20 ميغا بايت أو أكبر.

متطلباتي متشابهة ، لكني أرغب في حفظ الملف على الخادم (أو S3) وإعطاء رابط لتنزيله إما في لوحة معلومات التطبيق أو البريد الإلكتروني. أرى إمكانية القيام بذلك ، إذا وجدت شيئًا سأقوم بتحديثه هنا.

لدي مشكلة في معالجة الخادم والتي تستهلك كمية كبيرة من ذاكرة الوصول العشوائي وحجم تخصيص ذاكرة البرنامج النصي الافتراضي هو 60 ميجابايت.
انظر إلى memory_limit في ملف php.ini
حد وقت التنفيذ max_execution_time هو 60.
بعد زيادة القيمة ، تمكنت من تقديم طلب باستخدام التصدير بجانب الخادم.

لقد قمت بتعديل وظيفة excel لتخزين الملف بدلاً من التنزيل ، فهي تخزن الملف في تخزين / تصدير / مجلد.

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

لا أمتلك حاليًا كمية كبيرة من البيانات في بيئة التطوير الخاصة بي ، هل يمكنك إجراء التغيير أعلاه في إعدادك ومعرفة ما إذا كان قادرًا على إنشاء ملف Excel في هذا المجلد دون الوصول إلى غطاء الذاكرة؟

شيء آخر يجب ملاحظته هو أنني أستخدم Laravel 5.1 وبالتالي maatwebsite / excel الإصدار 2.1

ما أريد فعله حقًا هو وضع هذا في قائمة الانتظار بدلاً من ذلك والعودة إلى الصفحة برسالة تفيد بأن إنشاء التقرير قيد التقدم وأن رابط تنزيل الملف سيتم إرساله بالبريد الإلكتروني إلى معرفك المسجل "

في الإصدار 2.1 ، لست متأكدًا من كيفية وضع قائمة الانتظار ، لكنني وجدت هذا حيث يستخدمون " قائمة الانتظار " ، لكنني لست متأكدًا من كيفية تنفيذ ذلك.

إذن أي تحديثات حول هذا؟

إذن أي تحديثات حول هذا؟

إذا كان أي شخص يستخدم 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;
    }
}
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

jgatringer picture jgatringer  ·  3تعليقات

alejandri picture alejandri  ·  3تعليقات

ahmadbadpey picture ahmadbadpey  ·  3تعليقات

shadoWalker89 picture shadoWalker89  ·  3تعليقات

hohuuhau picture hohuuhau  ·  3تعليقات