Laravel-excel: 134217728λ°”μ΄νŠΈμ˜ ν—ˆμš©λœ λ©”λͺ¨λ¦¬ 크기가 μ†Œμ§„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2018λ…„ 07μ›” 19일  Β·  22μ½”λ©˜νŠΈ  Β·  좜처: Maatwebsite/Laravel-Excel

μ „μ œ 쑰건

  • [X] μ½”λ“œ μ™ΈλΆ€μ—μ„œ λ™μž‘μ„ μž¬ν˜„ν•  수 μžˆλŠ” λ¬Έμ œλŠ” Laravel Excel둜 κ²©λ¦¬λ©λ‹ˆλ‹€.
  • [X] λ¬Έμ œκ°€ 아직 μ œμΆœλ˜μ§€ μ•Šμ•˜λŠ”μ§€ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.
  • [X] 이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” PR이 μ œμΆœλ˜μ§€ μ•Šμ•˜λŠ”μ§€ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

버전

  • PHP 버전: 7.1.13
  • 라라벨 버전: 5.6
  • νŒ¨ν‚€μ§€ 버전: ^3.0

μ„€λͺ…

FromQuery μ˜΅μ…˜μœΌλ‘œ 내보내기λ₯Ό μ‹œλ„ν•˜λ©΄ Allowed memory size of 134217728 bytes exhausted λ©λ‹ˆλ‹€.

λ²ˆμ‹ 단계

μ˜ˆμƒλ˜λŠ” λ™μž‘:

λ‚΄ 문제λ₯Ό ν•΄κ²°ν•˜κ³  μ‹Άμ–΄μš” :)

μ‹€μ œ 행동:

μΆ”κ°€ 정보

namespace App\Exports;

use App\OldTransaction;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Http\Request;
use jDate;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;

class OldDepositExport implements FromQuery, ShouldQueue, WithMapping, WithHeadings, ShouldAutoSize
{
    use Exportable;

    /**
     * DepositExport constructor.
     * <strong i="27">@param</strong> Request $request
     */
    public function __construct(Request $request)
    {
    }

    public function headings(): array
    {
        return [
            'ID',
        ];
    }


    public function map($transaction): array
    {
        return [
            $transaction->id,
        ];
    }

    public function query()
    {
        return User::query()
            ->where('status', '=', 1)
            ->select(['id']);
    }
}

이 이미지λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€ https://i.imgur.com/yMgUqXP.jpg

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λˆ„κ΅¬μ—κ²Œμ„œ 닡을 κΈ°λŒ€ν•©λ‹ˆκΉŒ?

당사 μ†Œν”„νŠΈμ›¨μ–΄λŠ” 무료이며 μ˜€ν”ˆ μ†ŒμŠ€μ΄λ―€λ‘œ 당사 μ†Œν”„νŠΈμ›¨μ–΄ μ‚¬μš©μ€ 선택 μ‚¬ν•­μž…λ‹ˆλ‹€. λ‹Ήμ‚¬λŠ” μ–΄λ– ν•œ μ±…μž„λ„ 지지 μ•ŠμœΌλ©° 지원할 μ˜λ¬΄λ„ μ—†μŠ΅λ‹ˆλ‹€. μ΅œμ„ μ„ λ‹€ν•΄ μ§€μ›ν•˜κ² μŠ΅λ‹ˆλ‹€.

μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό μƒμ—…μ μœΌλ‘œ μ‚¬μš©ν•˜κ³  μ •κ΅ν•œ 지원이 ν•„μš”ν•˜κ±°λ‚˜ κΈ΄κΈ‰ν•˜κ²Œ ν•„μš”ν•œ 경우 μƒμ—…μ μœΌλ‘œ μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. [email protected] λ˜λŠ” μ „ν™” +31 (0)10 744 9312둜 μ—°λ½ν•˜μ‹­μ‹œμ˜€.

λͺ¨λ“  22 λŒ“κΈ€

아무도 λ‚˜λ₯Ό λ„μšΈ 수 μžˆμŠ΅λ‹ˆκΉŒ?

4 일. 닡이 μ—†μŠ΅λ‹ˆλ‹€ :-(

λˆ„κ΅¬μ—κ²Œμ„œ 닡을 κΈ°λŒ€ν•©λ‹ˆκΉŒ?

당사 μ†Œν”„νŠΈμ›¨μ–΄λŠ” 무료이며 μ˜€ν”ˆ μ†ŒμŠ€μ΄λ―€λ‘œ 당사 μ†Œν”„νŠΈμ›¨μ–΄ μ‚¬μš©μ€ 선택 μ‚¬ν•­μž…λ‹ˆλ‹€. λ‹Ήμ‚¬λŠ” μ–΄λ– ν•œ μ±…μž„λ„ 지지 μ•ŠμœΌλ©° 지원할 μ˜λ¬΄λ„ μ—†μŠ΅λ‹ˆλ‹€. μ΅œμ„ μ„ λ‹€ν•΄ μ§€μ›ν•˜κ² μŠ΅λ‹ˆλ‹€.

μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό μƒμ—…μ μœΌλ‘œ μ‚¬μš©ν•˜κ³  μ •κ΅ν•œ 지원이 ν•„μš”ν•˜κ±°λ‚˜ κΈ΄κΈ‰ν•˜κ²Œ ν•„μš”ν•œ 경우 μƒμ—…μ μœΌλ‘œ μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. [email protected] λ˜λŠ” μ „ν™” +31 (0)10 744 9312둜 μ—°λ½ν•˜μ‹­μ‹œμ˜€.

μ•Œκ² μŠ΅λ‹ˆλ‹€. 이 문제λ₯Ό 닫지 λ§ˆμ‹­μ‹œμ˜€. λˆ„κ΅°κ°€κ°€ 이것을 κ³ μΉ  수 μžˆμŠ΅λ‹ˆλ‹€.

감사 ν•΄μš”

php λ©”λͺ¨λ¦¬μ˜ λ¬Έμ œμΈκ²ƒ 같은데 데이터가 λ„ˆλ¬΄λ§Žμ•„μ„œ λ©”λͺ¨λ¦¬κ°€ λ„˜μΉ¨.. λΌμ΄λΈŒλŸ¬λ¦¬μ™€ 관련이 μ—†μŠ΅λ‹ˆλ‹€.

@jlcarpioe 거의 200k 행이 μžˆμŠ΅λ‹ˆλ‹€. μ‹œνŠΈμ— 행을 μΆ”κ°€ν•  λ•Œ λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€.

php.iniμ—μ„œ memory_limitλ₯Ό μ΅œλŒ€ν™”ν•˜λ €κ³  ν–ˆμŠ΅λ‹ˆκΉŒ?

@bagana89 쒋은 해결책이 μ•„λ‹™λ‹ˆλ‹€.

κ·€ν•˜μ˜ 문제λ₯Ό μž¬ν˜„ν•  수 μ—†μŠ΅λ‹ˆλ‹€. κ³΅μœ ν•˜μ‹  μ½”λ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 300K ν–‰μ˜ μ‚¬μš©μž ν…Œμ΄λΈ”μ„ 내보낼 수 μžˆμŠ΅λ‹ˆλ‹€. PhpSpreadsheetλŠ” 맀번 컀지고 μžˆλŠ” 톡합 λ¬Έμ„œλ₯Ό μ—΄μ–΄μ•Ό ν•˜λ―€λ‘œ λͺ¨λ“  μž‘μ—…μ—μ„œ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ μ¦κ°€ν•œλ‹€λŠ” 점에 μœ μ˜ν•˜μ‹­μ‹œμ˜€. 이 ν”„λ‘œμ„ΈμŠ€μ— 더 λ§Žμ€ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜λŠ” 데 μ•„λ¬΄λŸ° λ¬Έμ œκ°€ μ—†μŠ΅λ‹ˆλ‹€. ν• λ‹Ήλœ λ©”λͺ¨λ¦¬κ°€ λ§Žμ§€ μ•Šμ€ 것 κ°™μ•„μ„œ λ„ˆλ¬΄ 빨리 μ˜€λ²„ν”Œλ‘œλ©λ‹ˆλ‹€.

λͺ¨λ“  μž‘μ—…μ—μ„œ 톡합 λ¬Έμ„œ μ—΄ 차원을 λ‹€μ‹œ κ³„μ‚°ν•˜λ―€λ‘œ ShouldAutoSize λ₯Ό μ‚­μ œν•˜λŠ” 것이 κ°€μž₯ μ’‹μŠ΅λ‹ˆλ‹€. μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것보닀 훨씬 더 λ§Žμ€ λ©”λͺ¨λ¦¬κ°€ ν•„μš”ν•©λ‹ˆλ‹€.

1GB의 램이 ν• λ‹Ήλ˜μ—ˆμ§€λ§Œ μ—¬μ „νžˆ saeedvaziry와 λ™μΌν•œ κ²°κ³Όκ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.
v2.1μ—μ„œ v3.1둜 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν–ˆμŠ΅λ‹ˆλ‹€. λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜λ„λ‘ 동기λ₯Ό λΆ€μ—¬ν•œ v2.1κ³Ό λ™μΌν•œ λ¬Έμ œκ°€ μžˆμ—ˆμ§€λ§Œ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. v2.1의 Excel::createλŠ” 좜λ ₯ μŠ€νƒ€μΌμ„ μ§€μ •ν•˜λŠ” 것이 훨씬 더 μ‰¬μ› μŠ΅λ‹ˆλ‹€.

(FromQueryλ₯Ό μ‚¬μš©ν•˜μ—¬) 내보낼 λ•Œ 청크가 잘 μž‘λ™ν•˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€(λŒ€λŸ‰μ˜ λ©”λͺ¨λ¦¬ μ‚¬μš© - μ•½ 200,000개의 λ ˆμ½”λ“œμ— λŒ€ν•΄ μ΅œλŒ€ 3Gig). κ·ΈλŸ¬λ‚˜ κ°€μ Έμ˜€κΈ°λŠ” 청킹을 μ‚¬μš©ν•˜μ—¬ 잘 μž‘λ™ν•©λ‹ˆλ‹€. (λ©”λͺ¨λ¦¬λŠ” 50MBλ₯Ό μ΄ˆκ³Όν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€)

λ‚˜λŠ” 15,000 개의 λ ˆμ½”λ“œ 만 가지고 있으며 λ™μΌν•œ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. μ–΄λ–‘ν•΄?

이것은 였λ₯˜μž…λ‹ˆλ‹€:

[2019-11-24 22:39:59] local.ERROR: ν—ˆμš©λœ λ©”λͺ¨λ¦¬ 크기 134217728λ°”μ΄νŠΈ μ†Œμ§„(18874368λ°”μ΄νŠΈ ν• λ‹Ή μ‹œλ„) {"μ˜ˆμ™Έ":"[객체] (Symfony\Component\Debug\Exception\FatalErrorException( μ½”λ“œ: 1): C:\wamp64\www\.....\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Collection\Cells.php:421μ—μ„œ 134217728λ°”μ΄νŠΈμ˜ ν—ˆμš© λ©”λͺ¨λ¦¬ 크기가 μ†Œμ§„λ˜μ—ˆμŠ΅λ‹ˆλ‹€(18874368λ°”μ΄νŠΈ ν• λ‹Ή μ‹œλ„). )
[μŠ€νƒ 좔적]

0 {메인}

"}

php.iniμ—μ„œ ν—ˆμš©λ˜λŠ” λ©”λͺ¨λ¦¬ μ œν•œμ„ λŠ˜λ¦¬κ±°λ‚˜ ini_set을 μ‚¬μš©ν•˜μ—¬ λ™μ μœΌλ‘œ μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

1Gλ₯Ό 가지고 μžˆμ§€λ§Œ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€

ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹€ν–‰ν•  λ•Œ php-cli ν”„λ‘œμ„ΈμŠ€κ°€ μ†ŒλΉ„ν•˜λŠ” λ©”λͺ¨λ¦¬λŠ” μ–Όλ§ˆμž…λ‹ˆκΉŒ? 그러면 1Gig 이상이어야 ν•©λ‹ˆλ‹€.

λ©”λͺ¨λ¦¬ μ œν•œμ€ ν™•μ‹€νžˆ λ¬Έμ œκ°€ μ•„λ‹™λ‹ˆλ‹€. phpinfo에 λ”°λ₯΄λ©΄ 4GB둜 μ„€μ •λ˜μ–΄ μžˆλŠ”λ° μ—¬μ „νžˆ 이 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 같은 λ¬Έμ œκ°€μžˆλ‹€

'μ†”λ£¨μ…˜'은 νŒŒμΌμ„ μ—¬λŸ¬ 파일둜 λΆ„ν• ν•˜μ—¬ κ·Έ 사이에 λ©”λͺ¨λ¦¬λ₯Ό ν•΄μ œν•œ λ‹€μŒ λͺ¨λ“  νŒŒμΌμ„ λ³‘ν•©ν•˜κ³  λ³‘ν•©λœ 응닡을 λ³΄λƒ…λ‹ˆλ‹€.

단점:

  • μž„μ‹œ νŒŒμΌμ„ μœ„ν•œ 더 λ§Žμ€ 곡간
  • 더 λ§Žμ€ μ‹œκ°„ μ†Œμš”(비지λŠ₯적 루프)
  • μΆ”κ°€ μ½”λ“œ ν•„μš”(μ¦‰μ‹œ μ‚¬μš© λΆˆκ°€)

μž₯점:

  • νš¨κ³Όκ°€μžˆλ‹€

λ™μΌν•œ 문제, λ©”λͺ¨λ¦¬ μ œν•œμ€ 512MB, 4K ν–‰μž…λ‹ˆλ‹€.

λ§ˆμ§€λ§‰ ν•΄κ²°μ±…
이것은 였래된 κ²ƒμ΄μ§€λ§Œ μ§€κΈˆ 이 글을 읽고 μžˆλŠ” μ‚¬λžŒμ€ μ•Œ 것이닀.
ToModel λ˜λŠ” ToCollection을 κ°€μ Έμ˜€κ±°λ‚˜ λ‚΄λ³΄λ‚΄λŠ” 경우 ν•΄λ‹Ή ν”„λ‘œμ„ΈμŠ€μ—λŠ” λ³€ν™˜μ„ μœ„ν•΄ λ§‰λŒ€ν•œ λ©”λͺ¨λ¦¬ 할당이 ν•„μš”ν•©λ‹ˆλ‹€.
데이터λ₯Ό μ»¬λ ‰μ…˜ λ˜λŠ” λ°°μ—΄κ³Ό 같은 μ‚¬μš© κ°€λŠ₯ν•œ ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

이 경우 ToModel λ˜λŠ” ToCollectλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šκ³  ν”„λ‘œμ„ΈμŠ€λ₯Ό μš°νšŒν•˜κ³  OnEachRowλ₯Ό κ΅¬ν˜„ν•˜μ—¬ μˆ˜λ™μœΌλ‘œ μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Ό ν•©λ‹ˆλ‹€.
Excel Row 개체λ₯Ό 전달할 onRow λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. WithHeadingRowλ₯Ό κ΅¬ν˜„ν•˜μ—¬ μ—°κ΄€ λ°°μ—΄λ‘œ ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€.
이 $row->toArray()λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό μ–»κ³  μ›ν•˜λŠ” λŒ€λ‘œ μ²˜λ¦¬ν•˜μ‹­μ‹œμ˜€. λΉ λ₯΄κ³  μ‰½κ²Œ μ‘°μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μΆ”μ‹ : μ—¬μ „νžˆ λ©”λͺ¨λ¦¬ μ œν•œ 였λ₯˜κ°€ λ°œμƒν•˜λ©΄ λ‹€μŒκ³Ό 같이 λ§ˆμ§€λ§‰ 쀄에 return 문을 μΆ”κ°€ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.
λ°˜ν’ˆ;

감사 ν•΄μš”

λ‚˜λŠ” 같은 λ¬Έμ œκ°€ μžˆμ—ˆκ³  @MoFoLuWaSo 의 μ œμ•ˆμœΌλ‘œ +128Mb λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ„ 54Mb둜 μ€„μ˜€μŠ΅λ‹ˆλ‹€.

1) DTOλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€. λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ„ κ°€μž₯ 많이 μ€„μ˜€μŠ΅λ‹ˆλ‹€.
2) DTO의 속성을 μ£Όλ¬Έν•˜κ³  withMapping μ œκ±°ν•©λ‹ˆλ‹€.
3) ShouldAutoSize 제거

@saedvz의 경우 λ‹€μŒκ³Ό κ°™μ•„μ•Ό ν•©λ‹ˆλ‹€.

namespace App\DataTransferObjects;

class OldDepositRow
{
    public int $id;
    public string $created_at;
}

그리고

namespace App\Exports;

use App\DataTransferObjects\OldDepositRow;

class OldDepositExport implements FromCollection, ShouldQueue, WithHeadings
{
    use Exportable;

    public function headings(): array
    {
        return [
            'ID',
        ];
    }

    public function collection()
    {
        $users = User::query()
            ->where('status', '=', 1)
            ->select(['id']);

        return $users->map(
           function ($user) {
                $row = new OldDepositRow();
                $row->transaction_id = $user->transaction->id;

                // cast objects like Carbon or BigDecimal to string
                $row->created_at = $user->transaction->created_at->format('d-m-Y');

                return $row;
            }
        );
    }
}
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰