Asked Apr 17th, 4:17 AM 106 0 2
  • 106 0 2
+1

Export excel dữ liệu lớn bằng Maatwebsite 3.1 bị timeout

Share
  • 106 0 2

Mình có dùng package Maatwebsite để làm xuất Excel thì bị timeout khi export nhiều dữ liệu, mình đã dùng ->queue() hoặc ShouldQueue nhưng vẫn không được. Đây là code của mình

File xử lý Export

<?php

namespace App\Exports;

use App\Models\Txn;
use Illuminate\Queue\SerializesModels;
use Maatwebsite\Excel\Events\AfterSheet;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithEvents;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;

class TxnsExport implements FromQuery, ShouldQueue, WithHeadings, ShouldAutoSize, WithMapping, WithEvents
{
	use Exportable, SerializesModels;

	/**
     * @return array
     */
    public function registerEvents(): array
    {
        return [
            AfterSheet::class    => function(AfterSheet $event) {
            	$styleArray = [
				    'font' => [
				        'bold' => true,
				    ],
				    'alignment' => [
				        'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
				        'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
				    ],
				];
                $cellRange = 'A1:W1'; // All headers
                $event->sheet->getDelegate()
			                ->getStyle($cellRange)
			                ->applyFromArray($styleArray);
            },
        ];
    }

	public function headings(): array
    {
        return [
            'Mã người dùng',
            'Mã giao dịch',
            'Loại giao dịch',
            'Trạng thái',
            'Từ/Đến',
            'Số tham chiếu',
            'Số tham chiếu ngân hàng',
            'Số dư đầu',
            'Số tiền',
            'Phí',
            'Số dư cuối',
            'Thời gian'
        ];
    }

	/**
    * @var Txn $txn
    */
    public function map($txn): array
    {
        return [
            $txn->user_id,
            $txn->id,
            $txn->type_label,
            $txn->stat_label,
            $txn->src_des,
            $txn->ref_no,
            $txn->bank_ref_no,
            number_format($txn->opening_balance, 0, ',', '.'),
            number_format($txn->amount, 0, ",", "."),
            number_format($txn->fee_amount, 0, ",", "."),
            number_format($txn->balance, 0, ",", "."),
            ($txn->created_at == '0000-00-00 00:00:00' || $txn->created_at == '-0001-11-30 00:00:00') ? '' :
            date('d-m-Y | H:i:s',strtotime($txn->created_at)),
        ];
    }

    public function query()
    {
        return Txn::select('id','user_id','created_at','type','stat','src_des','ref_no','bank_ref_no','opening_balance','amount','fee_amount','balance','created_at')
        		->orderBy('id','desc');
    }
}

Controller


	public function exportExcel()
	{
		return (new TxnsExport)->download('txns_'.date('YmdHis').'.xlsx');
	}
    

2 ANSWERS


Answered Apr 17th, 6:36 AM
+1

Bạn thử config max-execution-time của php lên xem. Khả năng cao do export mất quá nhiều thời gian vượt quá timeout của php.

Với việc export bạn có thể dùng package fast-excel xem. cái Maatwebsite nó tích hợp quá nhiều thứ dẫn đến tốn bộ nhớ cũng như tốc độ không cao.

Fast-excel họ có test tốc độ so với Maatwebsite (Don't trust benchmarks).

Share
Tuan Anh Nguyen @TuanAnh9996
Apr 17th, 6:55 AM

chỉnh thời gian timeout lên thì khi dữ liệu lớn hơn nữa thì lại phải tăng thời gian đấy lên bạn ơi @@, mình đang không biết sao cái queue nó lại không chạy

0
| Reply
Share
Lê Vĩnh Thiện @le.vinh.thien
Apr 17th, 5:11 PM

@TuanAnh9996 nhưng mình nghĩ trc hết nên xem lại xem xử lý ntn vì với 10k dữ liệu cũng tầm 10s thôi. bỏ queue đi xem bt có chạy ko đã.

Mà mình đang ko hiểu sao dùng queue mà bạn lại return download thế kia nhỉ? nếu viết như vậy đâu ra kết quả gì vì queue là background job. Hay chỗ đó bạn muốn lưu lại file export? nếu muốn lưu phải dùng kiểu khác.

+1
| Reply
Share
Answered Apr 19th, 12:17 AM
0

Mình cũng gặp lỗi tương tự khi cố export khoảng 25k rows, cuối cùng mình chọn giải pháp là sử dụng laravel chunk query khi load từ database để load khoảng 1k rows mỗi lần và dùng hàm fputcsv() của PHP để write file sau đó cho client download file đó về, cũng mất khoảng 2 - 3p. Tuy nhiên thì Maatwebsite cũng hỗ trợ export from query. Bạn tìm hiểu tại đây: https://docs.laravel-excel.com/3.1/exports/from-query.html Hope it helps 😃

Share
Tuan Anh Nguyen @TuanAnh9996
Apr 19th, 2:48 AM

@duynam.dev mình cũng dùng from query của Maatwebsite mà tình hình khả quan cho đến khi mình load 35k rows đổ lên, time out vỡ mồm 😄

0
| Reply
Share