Laravel5.8 Goodby CSV를 사용하여 CSV 파일 다운로드 구현

Laravel과 Goodby CSV를 사용하여 CSV 출력을하는 처리를 구현할 기회가 있었으므로 내용을 정리하고 싶습니다.

Goodby CSV란?



Goodby CSV는 PHP 5.3 이상에서 사용할 수 있는 메모리 효율이 높고 유연하고 확장 가능한 오픈 소스 CSV 가져오기/내보내기 라이브러리입니다.
또한 SJIS-win, EUC-JP, UTF-8 등의 문자 코드도 지원합니다.

@suin 님과 @reoring 님이 만든 라이브러리에 감사드립니다 🙏🙏🙏
GitHub는 이쪽 ⭐️ goodby/csv ⭐️

환경


  • PHP 7.3.6
  • Laravel 5.8.27
  • MySQL 8.0.16

  • ※새롭게 Laravel 프로젝트를 인스톨 해 마이그레이션 실행까지 끝난 상태로부터 시작하고 있습니다.

    Goodby CSV 설치


    $ composer require goodby/csv
    

    CSV 다운로더 서비스 클래스 구현


    app/Services/CsvDownloader.php 를 새로 작성합니다.
    <?php
    
    namespace App\Services;
    
    use App\User;
    use Goodby\CSV\Export\Standard\Exporter;
    use Goodby\CSV\Export\Standard\ExporterConfig;
    use Illuminate\Database\Eloquent\Collection;
    use Symfony\Component\HttpFoundation\StreamedResponse;
    
    final class CsvDownloader
    {
        /**
         * @return StreamedResponse
         */
        public function download(): StreamedResponse
        {
            $callback = function () {
                $config = new ExporterConfig();
                $config
                    ->setDelimiter(',') // 区切り文字
                    ->setEnclosure('"') // 囲み文字
                    ->setEscape('\\') // エスケープ文字
                    ->setToCharset(null) // 出力ファイルの文字コード
                    ->setFromCharset('auto') // 読み込み元の文字コード
                    ->setColumnHeaders($this->makeCsvHeader()); // CSVの1列目のヘッダー行
                $exporter = new Exporter($config);
                $exporter->export('php://output', $this->makeCsvBody());
            };
    
            return response()->streamDownload($callback, $this->makeFilename(), $this->makeResponseHeader());
        }
    
        /**
         * @return array
         */
        private function makeCsvHeader(): array
        {
            return ['名前', 'メールアドレス', '作成日'];
        }
    
        /**
         * @return array
         */
        private function makeCsvBody(): array
        {
            $users = $this->getUsers();
    
            $data = [];
            foreach ($users as $user) {
                $data[] = $this->toCsvFromUser($user);
            }
    
            return $data;
        }
    
        /**
         * @param User $user
         * @return array
         */
        private function toCsvFromUser(User $user): array
        {
            return [
                $user->name,
                $user->email,
                $user->created_at,
            ];
        }
    
        /**
         * @return Collection
         */
        private function getUsers(): Collection
        {
            return User::all();
        }
    
        /**
         * @return array
         */
        private function makeResponseHeader(): array
        {
            return [
                'Content-type' => 'text/csv',
                'Cache-Control' => 'must-revalidate, no-cache',
                'Expires' => '0',
            ];
        }
    
        /**
         * @return string
         */
        private function makeFilename(): string
        {
            return 'ユーザー一覧.csv';
        }
    }
    

    보충



    긴 코드가 되어 버렸습니다만, Goodby CSV를 사용하고 있는 부분은 여기입니다.
    $config = new ExporterConfig();
    $config
        ->setDelimiter(',') // 区切り文字
        ->setEnclosure('"') // 囲み文字
        ->setEscape('\\') // エスケープ文字
        ->setToCharset(null) // 出力ファイルの文字コード
        ->setFromCharset('auto') // 読み込み元の文字コード
        ->setColumnHeaders($this->makeCsvHeader()); // CSVの1列目のヘッダー行
    $exporter = new Exporter($config);
    $exporter->export('php://output', $this->makeCsvBody());
    

    출력 설정은 ExporterConfig 클래스에서 실시합니다.
    CSV의 1행의 헤더행(setColumnHeaders)의 설정 이외는 디폴트치를 사용하고 있습니다.
    원하는대로 사용자 정의하여 사용하십시오.

    또한 희귀 D 째. MD에 쓰여진 배열에서 내보내는 방법을 사용합니다.

    파일 다운로드 (스트림 다운로드)



    출력 CSV를 디스크에 쓰지 않고 문자열 응답을 통해 다운로드하려면 streamDownload 메서드를 사용합니다.
  • streamDownload
  • ResponseFactory.php

  • 라우팅 정의


    routes/web.php 에 다음 라우팅을 추가합니다.
    Route::get('/users', 'UsersController@index');
    Route::get('/users/download', 'UsersController@download');
    

    컨트롤러 만들기


    src/app/Http/Controllers/UsersController.php 를 새롭게 작성합니다.
    <?php
    
    namespace App\Http\Controllers;
    
    use App\User;
    use App\Services\CsvDownloader;
    use Illuminate\Http\Request;
    use Symfony\Component\HttpFoundation\StreamedResponse;
    
    class UsersController extends Controller
    {
        /**
         * @return array
         */
        public function index(): array
        {
            $users = User::all();
    
            return [
                'users' => $users,
            ];
        }
    
        /**
         * @return StreamedResponse
         */
        public function download(): StreamedResponse
        {
            return (new CsvDownloader())->download();
        }
    }
    

    테스트용 사용자 만들기


    $ php artisan tinker
    >>> factory(App\User::class, 10)->create();
    

    모델 팩토리 을 사용하여 10개의 테스트 데이터를 만듭니다.

    동작 확인


  • htp://127.0.0.1:10080/우세 rs



  • 사용자 목록이 json에서 반환되었습니다.
    콘트롤러로 배열을 돌려주면 Laravel측에서 json에 좋게 변환해 주기 때문에 확인할 때는 편리하네요😊

    이야기는 전혀 바뀌지 만 JSON Formatter 넣으면 편리합니다.
  • ht tp // 127.0.0.1 : 10080 / 우세 rs / 드w



  • 실제로 다운로드한 파일입니다.

    사이고에게



    Laravel과 Goodby CSV로 쉽게 CSV 출력 처리를 구현할 수있었습니다!

    좋은 웹페이지 즐겨찾기