Laravel-datatables: Ekspor Sisi Server 200000 catatan

Dibuat pada 31 Mar 2018  ·  19Komentar  ·  Sumber: yajra/laravel-datatables

Ringkasan masalah atau permintaan fitur

Ketika 200000 merekam cara mengekspor data. Ketika saya mengekspor data, "Ukuran memori yang diizinkan sebesar 134217728 byte habis" , pengecualian ini muncul.

Apa pilihan lain untuk mengekspor sejumlah besar data di yajra / datatable.

Berikan cara lain untuk mengekspor data dalam jumlah besar.

Kami memiliki jumlah ram yang terbatas di server.

Potongan kode masalah

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

Detail sistem

  • Sistem Operasi: Ubuntu 16.04
  • Versi PHP: 7.0.0.0
  • Versi Laravel: 5.5.0
  • Versi Laravel-Datatables: 8.0
  • Laravel-Datatables Buttons Versi: 3.1.0
performance question

Semua 19 komentar

Anda perlu menerapkan pembuat file excel Anda sendiri untuk menangani permintaan massal ini. Pada kelas ServiceDataTable Anda, Anda dapat mengganti metode protected function buildExcelFile() dan mungkin melakukan beberapa bagian, dll. Lihat dokumen laravel-excel untuk info lebih lanjut.

    /**
     * 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());
            });
        });
    }

Saya pikir kode Mengikuti membuat pengecualian
$this->getDataForExport();
Mendapat pengecualian saat sisi server editColumn() ditentukan atau digunakan
ada 200000 catatan.
Apakah ada cara lain untuk mendapatkan data tanpa pemrosesan atau tidak mengalokasikan lebih banyak memori.
Saya memiliki tautan berikut tetapi yajra yajra / laravel-datatables-buttons: ^ 3.1 namun tidak mendukung Laravel / Excel: 3.0
https://laravel-excel.maatwebsite.nl/docs/3.0/export/queued

Harus ada cara yang langsung mengekspor dari kueri atau cara yang fasih.

Saya menggunakan Postman untuk meniru operasi itu tetapi

Ukuran memori yang diizinkan sebesar 134217728 byte habis

pengecualian dilempar. Saya tidak memiliki baris yang digunakan untuk menghasilkan html, saya menggunakan rawColumns () untuk keluar dari html, Kueri saya membutuhkan 0,420 ms di phpmyadmin dan Pada 1,4 detik pertama.

Jika kami dapat menempatkan ini ke antrian, kami juga dapat menyimpannya ke folder di server dan kemudian memberikan tautan kepada pengguna untuk mengunduhnya.

Berterima kasih atas tanggapan Anda.

Saya menggunakannya di JQuery Datatable atau yajra datatable dan ingin mengekspor dari sisi server.

Menurut saya tidak layak untuk menyimpan ke folder di server, banyak masalah yang akan menimbulkan masalah.

Saya perlu streaming data.

Jumlah data dalam tanggapan berukuran 20MB atau lebih besar.

Persyaratan saya serupa, tetapi saya ingin menyimpan file ke server (atau S3) dan memberikan tautan untuk mengunduhnya baik di dasbor aplikasi atau email saya. Saya melihat kemungkinan melakukan ini, jika saya menemukan sesuatu yang akan saya perbarui di sini.

Saya memiliki masalah dengan pemrosesan di sisi server yang memakan banyak ram dan ukuran alokasi memori skrip default adalah 60MB.
Lihat memory_limit di php.ini
Batas waktu eksekusi max_execution_time adalah 60.
Setelah meningkatkan nilai, Anda dapat membuat permintaan menggunakan ekspor sisi server.

Saya memodifikasi fungsi excel untuk menyimpan file daripada mengunduh, itu menyimpan file di penyimpanan / ekspor / folder.

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

Saat ini saya tidak memiliki sejumlah besar data dalam pengembangan env saya, dapatkah Anda membuat perubahan di atas dalam pengaturan Anda dan melihat apakah itu dapat membuat excel di folder itu tanpa mencapai batas memori?

Hal lain yang perlu diperhatikan adalah saya menggunakan Laravel 5.1 jadi maatwebsite / excel versi 2.1

Yang benar-benar ingin saya lakukan adalah meletakkan ini dalam antrian dan kembali ke halaman dengan pesan bahwa pembuatan laporan sedang dalam proses dan tautan untuk mengunduh file akan dikirim ke email ke id terdaftar Anda "

dalam versi 2.1 tidak yakin bagaimana cara mengantri, tetapi saya menemukan ini di mana mereka menggunakan " Antrian Chunk ", tetapi saya tidak yakin bagaimana menerapkan ini.

Jadi ada update tentang ini?

Jadi ada update tentang ini?

Jika ada yang menggunakan Laravel Excel 3.0+, solusi atas tidak akan berfungsi. jadi Anda harus mengganti buildExcelFile() dengan menggunakan "Ekspor dalam Antrean" .

Atau saya melakukan sesuatu yang lain dengan menggunakan chunking juga tetapi dengan menciptakan sifat saya dan menggunakan CSV untuk melakukan pekerjaan saya dan ini contohnya

ada pembaruan?

Dimulai dengan Laravel 6 Anda dapat menggunakan LazyCollections untuk memuat hanya satu item dalam satu waktu di memori. Ini memperbaiki masalah kehabisan memori.

Hanya perlu memperluas kelas DataTable dan menulis DataTablesExportHandler yang disesuaikan.

Lihat inti saya

Nikmati!

@singhofmarco Bisakah Anda membuat contoh?

@singhofmarco Saya setuju, sudah memulai proyek v10 tahun lalu yang akan menggunakan LazyCollections tetapi tidak dapat melanjutkannya di atm.

Saya mengambil rute yang berbeda. Saya telah mengganti fungsi csv, memanggil Tabel Data dengan satu halaman data setiap kali, secara efektif memotong. Menggunakan fputcsv pada baris hasil sampai file selesai, lalu kembalikan konten file dalam Respon Laravel.

Tidak hanya batas memori tidak pernah tercapai lagi (hingga CSV itu sendiri tumbuh melampaui batas memori PHP, maka respons streaming mungkin lebih membantu), tetapi juga lebih dari dua kali lebih cepat ......

@ameenross jika memungkinkan dapatkah Anda membagikan kode Anda.

@karmendra Saya lebih suka tidak melakukannya, karena ini untuk versi Yajra Datatables yang lebih lama. Tapi pada dasarnya apa yang saya lakukan adalah menggabungkan beberapa nilai halaman & panjang dalam permintaan, memanggil kode yang biasanya mengembalikan halaman data untuk AJAX ( $this->ajax()->getData(true)['data'] dalam kasus saya). Saya memiliki kelas dasar untuk datatables yang memperluas kelas Yajra Datatable, dengan fungsi getCsv (memutuskan untuk tidak menimpa fungsi CSV, tapi itu tidak penting). Ini berlangsung terus menerus sampai tidak ada lagi halaman yang tersisa.

@ameenross Terima kasih yang sangat membantu. Saya akan mencoba ini.

Laravel Datatable :: v1.5.0
Ini solusi saya berdasarkan komentar @TheGeekyM , saya meninggalkannya jika itu membantu orang lain.
Saya membuat kelas ChunkedDatatableExportHandler yang mengimplementasikan FromQuery dan kemudian mengganti metode buildExcelFile di ServiceDataTables saya untuk menggunakannya.

<?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;
    }
}
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

shadoWalker89 picture shadoWalker89  ·  3Komentar

jackrsantana picture jackrsantana  ·  3Komentar

alejandri picture alejandri  ·  3Komentar

Mopster picture Mopster  ·  3Komentar

kamrava picture kamrava  ·  3Komentar