Yêu cầu thg 4 17, 2019 4:17 SA 1585 0 3
  • 1585 0 3
+2

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

Chia sẻ
  • 1585 0 3

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');
	}
    

3 CÂU TRẢ LỜI


Đã trả lời thg 4 17, 2019 6:36 SA
+2

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).

Chia sẻ
Avatar Nguyen Tuan Anh @TuanAnh9996
thg 4 17, 2019 6:55 SA

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

Avatar Lê Vĩnh Thiện @le.vinh.thien
thg 4 17, 2019 5:11 CH

@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.

thg 11 9, 2021 7:54 SA

@le.vinh.thien mình dùng export và download luôn thì với tầm 1k bản ghi, 100 cột thì thời giân tầm 1 phút liệu có ổn không b?

Avatar Lê Vĩnh Thiện @le.vinh.thien
thg 11 10, 2021 5:59 CH

@tab99 bạn thử debug xem khi export tốn nhiều thời gian nhất vào phần nào(query, create file, download?) từ đó cải thiện.

thg 11 12, 2021 5:40 SA

@le.vinh.thien mình có xem debug của laravel + trình duyệt nhưng mình chưa biết check time phần nào(query, create file, download) b có thể chỉ mình được không?

Avatar Lê Vĩnh Thiện @le.vinh.thien
thg 11 12, 2021 5:54 CH

@tab99 mỗi đoạn xử lý bạn hãy in ra log time, sau đó check logs của laravel thôi.

ví dụ

// controller
public function export() {
   $diffTime = microtime(true);
   // phần logic query DB
   //....
   $diffTime = microtime(true) -$diffTime;
    Log::debug( $diffTime);
    // phần logic query xử lý dữ liệu
   //....
   $diffTime= microtime(true) - $diffTime;
    Log::debug( $diffTime);
    // phần tạo xls file
   //....
   $diffTime= microtime(true) - $diffTime;
    Log::debug( $diffTime);
    return ...
}
Đã trả lời thg 4 19, 2019 12:17 SA
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 😃

Chia sẻ
Avatar Nguyen Tuan Anh @TuanAnh9996
thg 4 19, 2019 2:48 SA

@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 😄

Đã trả lời thg 11 9, 2021 7:52 SA
0

Không biết bạn thớt đã giải quyết vấn đề này được chưa nhỉ? Mình cũng đang gặp vấn đề tương tự 😦(

Chia sẻ
Avatar Phạm Tuấn Anh @phamtuananh760
thg 11 17, 2021 3:45 SA

https://github.com/rap2hpoutre/fast-excel#benchmarks mình dùng thằng này và đã giải quyết đk rồi

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí