Laravel-excel: Excel둜 νŒŒμΌμ„ μ—¬λŠ” λ™μ•ˆ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. 데이터가 μ†μƒλ˜μ—ˆκ±°λ‚˜ 파일 ν™•μž₯μžκ°€ 잘λͺ»λ˜μ—ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

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

μ „μ œ 쑰건

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

버전

  • PHP 버전: 7.1
  • 라라벨 버전: 5.5.*
  • νŒ¨ν‚€μ§€ 버전: ^3.0

μ„€λͺ…

FromQuery λ©”μ„œλ“œμ—μ„œ 파일 λ‹€μš΄λ‘œλ“œ.... 파일 λ‹€μš΄λ‘œλ“œ, XLSX νŒŒμΌμ„ μ—΄ λ•Œ Officeμ—μ„œ 였λ₯˜ λ©”μ‹œμ§€ μˆ˜μ‹ :
"Excelμ—μ„œ νŒŒμΌμ„ μ—΄ 수 μ—†μŠ΅λ‹ˆλ‹€.파일 ν˜•μ‹μ΄λ‚˜ 파일 ν™•μž₯μžκ°€ μœ νš¨ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 파일이 μ†μƒλ˜μ§€ μ•Šμ•˜λŠ”μ§€, 파일 ν™•μž₯μžκ°€ 파일 ν˜•μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€ ν™•μΈν•˜μ‹­μ‹œμ˜€."

λ²ˆμ‹ 단계

μ—¬κΈ° λ‚΄ 방법이 μžˆμŠ΅λ‹ˆλ‹€

namespace Modules\Profile\Exports;

use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;
use Modules\Profile\Entities\Profile;

class ProfileExport implements FromQuery
{
    use Exportable;

    public function __construct($range)
    {
        $this->start = $range['start'];
        $this->end = $range['end'];
    }

    public function query()
    {
      return Profile::query()->where('created_at', '>=', $this->start . ' 00:00:00')
                             ->where('created_at', '<=', $this->end . ' 23:59:59')
                             ->whereHas('user.roles', function($query){
                                  $query->where('id', 2);
                             });
    }
}

μ»¨νŠΈλ‘€λŸ¬μ—μ„œ μ΄λ ‡κ²Œ λΆˆλŸ¬μš”

//$request->start = '2018-01-01';
//$request->end = '2018-05-01';

$range = ['start'=>$request->start, 'end'=>$request->end];
return (new ProfileExport($range))->download($request->start . '-' . $request->end .'-pet-parent-signups.xlsx');

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

데이터와 ν•¨κ»˜ λ‹€μš΄λ‘œλ“œν•  파일

μ‹€μ œ 행동:

파일이 λ‹€μš΄λ‘œλ“œλ˜μ§€λ§Œ Excelμ—μ„œ νŒŒμΌμ„ μ—¬λŠ” λ™μ•ˆ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

μΆ”κ°€ 정보

μ›…λ³€μœΌλ‘œ 쿼리λ₯Ό ν…ŒμŠ€νŠΈν–ˆμœΌλ©° 데이터가 ν¬ν•¨λœ μ»¬λ ‰μ…˜μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

(https://user-images.githubusercontent.com/18451450/40511758-f61e6570-5f5d-11e8-9f37-0b594f60be59.png)

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

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,

이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 μ΄ν•΄ν•˜λŠ” 데 ν•˜λ£¨λ₯Ό λ³΄λƒ…λ‹ˆλ‹€. PHPSpreadSheetλŠ” PHP 버퍼λ₯Ό μ‚¬μš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. PHP ꡬ성에 따라 일뢀 κ²½κ³  λ˜λŠ” 였λ₯˜κ°€ 좜λ ₯을 λ°©ν•΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš©:

// in controller
ob_end_clean(); // this
ob_start(); // and this
return Excel::download(new MyExport, 'file.xls');

λ‚˜λ₯Ό μœ„ν•΄ ν•΄κ²°ν•©λ‹ˆλ‹€.
μ–΄μ©Œλ©΄ 그것은 μ–΄λ–€ μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

이 멋진 λΌμ΄λΈŒλŸ¬λ¦¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

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

λ˜ν•œ 미리 κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€ :)

특히 이 래퍼λ₯Ό μž‘μ„±ν•˜λŠ” 데 μ‹œκ°„μ„ ν• μ• ν•˜μ—¬ μ‹œμž‘ν•˜λ €λ©΄

PhpSpreadsheetμ—μ„œ μ—¬μ „νžˆ λ™μΌν•œ λ¬Έμ œμΈμ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ PHPExcelμ—λŠ” <?php μ—΄λ¦° νƒœκ·Έ μ•žμ— 곡백( )이 μžˆλŠ” 데 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. 과거에 이 였λ₯˜λ₯Ό μΌμœΌν‚€λŠ” 데 μ‚¬μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

nano λ˜λŠ” vim으둜 였λ₯˜ νŒŒμΌμ„ μ—΄ 수 μžˆμŠ΅λ‹ˆλ‹€.
PK μ•žμ— 곡백이 보이면 λ‹€μŒκ³Ό 같이 :
image
μ½”λ“œλ‚˜ κ³΅κΈ‰μ—…μ²΄μ—μ„œ 였λ₯˜κ°€ λ°œμƒν–ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. λ™μΌν•œ λ¬Έμ œκ°€ λ°œμƒν•˜μ—¬ 곡급업체 폴더 제거λ₯Ό μ²˜λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€. 잘 μž‘λ™ν•©λ‹ˆλ‹€ 벀더λ₯Ό λ‹€μ‹œ μ„€μΉ˜ν•œ ν›„

μ—¬λŸ¬λΆ„, λ¦¬λ“œν•΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€.

파일 μ‹œμž‘ 뢀뢄에 μΆ”κ°€ 쀄 λ°”κΏˆμ΄λ‚˜ λ­”κ°€κ°€ μžˆλ‹€λŠ” 것이 μ˜³λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. 아직 μΆ”μ ν•˜μ§€ μ•Šμ•˜μ§€λ§Œ CSV둜 μ „ν™˜ν•˜λ©΄ νŒŒμΌμ„ μ—΄ 수 있고 λ°μ΄ν„°λŠ” μžˆμ§€λ§Œ 첫 번째 행은 λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€....

μ’€ 더 μ‚΄νŽ΄λ³΄κ³  λ‚˜μœ 보고가 λŒμ•„μ˜΅λ‹ˆλ‹€. 쀄 λ°”κΏˆμœΌλ‘œ μ‹œμž‘ν•˜λŠ” νŒŒμΌμ„ 찾은 λ‹€μŒ

λ‚˜λŠ” 이것을 λ‹«κ³  λ¬Έμ œμ— λŒ€ν•œ 더 λ‚˜μ€ μ„€λͺ…κ³Ό ν•¨κ»˜ μƒˆ 것을 μ—΄ κ²ƒμž…λ‹ˆλ‹€. 빈 ν–‰μ˜ 좜처λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€

λ‚˜λŠ” 같은 문제λ₯Ό λ§Œλ‚¬λ‹€. λ‚΄κ°€ κ³ μ³€λ‹€

  • Excel::μ„œλ²„μ— νŒŒμΌμ„ μ €μž₯ν•˜κΈ° μœ„ν•œ μ €μž₯
  • return λ¦¬λ””λ ‰μ…˜( μŠ€ν† λ¦¬μ§€::url("μŠ€ν† λ¦¬μ§€/{$filename}" ));
    견본
    ```
    곡개 ν•¨μˆ˜ 내보내기(μš”μ²­ $request)
    {
    $filename = 'meal_list_'.date('YmdHis').'.xlsx';
     Excel::store(new MealExport($request), $filename, 'public');
     return redirect( Storage::url("storage/{$filename}" ));
}

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,

이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 μ΄ν•΄ν•˜λŠ” 데 ν•˜λ£¨λ₯Ό λ³΄λƒ…λ‹ˆλ‹€. PHPSpreadSheetλŠ” PHP 버퍼λ₯Ό μ‚¬μš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. PHP ꡬ성에 따라 일뢀 κ²½κ³  λ˜λŠ” 였λ₯˜κ°€ 좜λ ₯을 λ°©ν•΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš©:

// in controller
ob_end_clean(); // this
ob_start(); // and this
return Excel::download(new MyExport, 'file.xls');

λ‚˜λ₯Ό μœ„ν•΄ ν•΄κ²°ν•©λ‹ˆλ‹€.
μ–΄μ©Œλ©΄ 그것은 μ–΄λ–€ μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

이 멋진 λΌμ΄λΈŒλŸ¬λ¦¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,

이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 μ΄ν•΄ν•˜λŠ” 데 ν•˜λ£¨λ₯Ό λ³΄λƒ…λ‹ˆλ‹€. PHPSpreadSheetλŠ” PHP 버퍼λ₯Ό μ‚¬μš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. PHP ꡬ성에 따라 일뢀 κ²½κ³  λ˜λŠ” 였λ₯˜κ°€ 좜λ ₯을 λ°©ν•΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš©:

// in controller
ob_end_clean(); // this
ob_start(); // and this
return Excel::download(new MyExport, 'file.xls');

λ‚˜λ₯Ό μœ„ν•΄ ν•΄κ²°ν•©λ‹ˆλ‹€.
μ–΄μ©Œλ©΄ 그것은 μ–΄λ–€ μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

이 멋진 λΌμ΄λΈŒλŸ¬λ¦¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

μ™„λ²½ν•œ λ‹΅λ³€ κ°μ‚¬ν•©λ‹ˆλ‹€

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,

이 μ†”λ£¨μ…˜:

ob_end_clean(); // this
ob_start(); // and this
return Excel::download(new MyExport, 'file.xls');

μž‘λ™ν•˜κ³  μ†μƒλœ 문제λ₯Ό ν•΄κ²°ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ—¬μ „νžˆ Xlsx/Xlsλ₯Ό μ‚¬μš©ν•˜μ—¬ λ‚΄λ³΄λ‚΄λŠ” 데 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.
λ‹€μš΄λ‘œλ“œν•œ νŒŒμΌμ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
image

이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 방법에 λŒ€ν•œ 아이디어가 μžˆμŠ΅λ‹ˆκΉŒ?

κ³ λ§ˆμ›Œ !

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,

이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 μ΄ν•΄ν•˜λŠ” 데 ν•˜λ£¨λ₯Ό λ³΄λƒ…λ‹ˆλ‹€. PHPSpreadSheetλŠ” PHP 버퍼λ₯Ό μ‚¬μš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. PHP ꡬ성에 따라 일뢀 κ²½κ³  λ˜λŠ” 였λ₯˜κ°€ 좜λ ₯을 λ°©ν•΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš©:

// in controller
ob_end_clean(); // this
ob_start(); // and this
return Excel::download(new MyExport, 'file.xls');

λ‚˜λ₯Ό μœ„ν•΄ ν•΄κ²°ν•©λ‹ˆλ‹€.
μ–΄μ©Œλ©΄ 그것은 μ–΄λ–€ μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

이 멋진 λΌμ΄λΈŒλŸ¬λ¦¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

Love You man.. λ‚΄ 머리λ₯Ό ꡬ해쀬어...

PhpSpreadsheetμ—μ„œ μ—¬μ „νžˆ λ™μΌν•œ λ¬Έμ œμΈμ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ PHPExcelμ—λŠ” <?php μ—΄λ¦° νƒœκ·Έ μ•žμ— 곡백( )이 μžˆλŠ” 데 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. 과거에 이 였λ₯˜λ₯Ό μΌμœΌν‚€λŠ” 데 μ‚¬μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš” @patrickbrowers
κ·€ν•˜μ˜ μ˜κ²¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.
λ‚˜λ₯Ό μœ„ν•΄ ν•΄κ²°ν•©λ‹ˆλ‹€.

ajaxλ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€μš΄λ‘œλ“œν•˜λŠ” 경우,
κ·€ν•˜μ˜ ajax μš”μ²­μ— responseType: 'blob' λ₯Ό μΆ”κ°€ν•˜μ‹­μ‹œμ˜€(μ €λŠ” axiosλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€).

λ‚΄ 예제 μ½”λ“œ:

axios.post('/path/to/export', data, {
    responseType: 'blob',
})
.then(response => {
    const filename = 'file.xlsx';
    let blob = new Blob([response.data], {
        type: 'application/octet-stream',
    });

    if (typeof window.navigator.msSaveBlob !== 'undefined') {
        // IE workaround for "HTML7007: One or more blob URLs were
        // revoked by closing the blob for which they were created.
        // These URLs will no longer resolve as the data backing
        // the URL has been freed."
        window.navigator.msSaveBlob(blob, filename);
    } else {
        let blobURL = window.URL.createObjectURL(blob);
        let tempLink = document.createElement('a');
        tempLink.style.display = 'none';
        tempLink.href = blobURL;
        tempLink.download = filename;
        tempLink.click();
        window.URL.revokeObjectURL(blobURL);
    }
})

responseType: 'blob' κ°€ μ—†μœΌλ©΄ λ‹€μš΄λ‘œλ“œν•œ νŒŒμΌμ„ μ—΄ 수 μ—†μŠ΅λ‹ˆλ‹€.

ajaxλ₯Ό μ‚¬μš©ν•˜μ—¬ λ‹€μš΄λ‘œλ“œν•˜λŠ” 경우,
κ·€ν•˜μ˜ ajax μš”μ²­μ— responseType: 'blob' λ₯Ό μΆ”κ°€ν•˜μ‹­μ‹œμ˜€(μ €λŠ” axiosλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€).

λ‚΄ 예제 μ½”λ“œ:

axios.post('/path/to/export', data, {
    responseType: 'blob',
})
.then(response => {
    const filename = 'file.xlsx';
    let blob = new Blob([response.data], {
        type: 'application/octet-stream',
    });

    if (typeof window.navigator.msSaveBlob !== 'undefined') {
        // IE workaround for "HTML7007: One or more blob URLs were
        // revoked by closing the blob for which they were created.
        // These URLs will no longer resolve as the data backing
        // the URL has been freed."
        window.navigator.msSaveBlob(blob, filename);
    } else {
        let blobURL = window.URL.createObjectURL(blob);
        let tempLink = document.createElement('a');
        tempLink.style.display = 'none';
        tempLink.href = blobURL;
        tempLink.download = filename;
        tempLink.click();
        window.URL.revokeObjectURL(blobURL);
    }
})

responseType: 'blob' κ°€ μ—†μœΌλ©΄ λ‹€μš΄λ‘œλ“œν•œ νŒŒμΌμ„ μ—΄ 수 μ—†μŠ΅λ‹ˆλ‹€.

κ°μ‚¬ν•©λ‹ˆλ‹€!! λ‚΄ 생λͺ…을 κ΅¬ν•˜μ‹­μ‹œμ˜€. λ‚΄ 보낸 νŒŒμΌμ„ μ†μƒμ‹œν‚¨ PHP μ½”λ“œ 쀄을 계속보고 μžˆμŠ΅λ‹ˆλ‹€. κ²°κ³ΌλŠ” axiosμž…λ‹ˆλ‹€

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„,

이 μž‘λ™ν•˜μ§€ μ•ŠλŠ” λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯을 μ΄ν•΄ν•˜λŠ” 데 ν•˜λ£¨λ₯Ό λ³΄λƒ…λ‹ˆλ‹€. PHPSpreadSheetλŠ” PHP 버퍼λ₯Ό μ‚¬μš©ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. PHP ꡬ성에 따라 일뢀 κ²½κ³  λ˜λŠ” 였λ₯˜κ°€ 좜λ ₯을 λ°©ν•΄ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš©:

// in controller
ob_end_clean(); // this
ob_start(); // and this
return Excel::download(new MyExport, 'file.xls');

λ‚˜λ₯Ό μœ„ν•΄ ν•΄κ²°ν•©λ‹ˆλ‹€.
μ–΄μ©Œλ©΄ 그것은 μ–΄λ–€ μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

이 멋진 λΌμ΄λΈŒλŸ¬λ¦¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€.

@Leenzuur 감사 @Leenzuur λ°©μ‹μœΌλ‘œ μˆ˜μ •ν•  수 μžˆλŠ” 방법이 μžˆλŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€. 10개 λͺ¨λΈμ— λŒ€ν•΄ 10개의 내보내기 ν΄λž˜μŠ€κ°€ μžˆλŠ” 경우 λ‹€μš΄λ‘œλ“œν•  λ•Œ 10개 μœ„μΉ˜λ₯Ό μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€.

이 λ¬Έμ œλŠ” μˆ˜μΆœμ— μ•„λ¬΄λŸ° λ³€ν™” 없이 였늘 λ‚˜μ—κ²Œ λ°œμƒν•˜κΈ° μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. @leenzuur μ½”λ“œ μƒ˜ν”Œμ„ μ‚¬μš©ν•˜μ—¬ λͺ‡ μ‹œκ°„μ˜ 연ꡬ 끝에 μˆ˜μ •ν–ˆμŠ΅λ‹ˆλ‹€.

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