バックエンド

【PHP】【Laravel】CSVエクスポートの方法〜5つのポイント〜

ちょっと前にPHPでCSVインポートをする方法を書きまして。

今回はCSVエクスポート(ダウンロード)の方法をまるっとまとめたいと思います。

Sponsored link

PHPでCSVエクスポートをするコード[laravel]

コントローラーのコードはこんな感じです。

    public function export(Request $request)
    {
        $headers = [ //ヘッダー情報
            'Content-type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename=csvexport.csv',
            'Pragma' => 'no-cache',
            'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
            'Expires' => '0',
        ];

        $callback = function() 
        {
            
            $createCsvFile = fopen('php://output', 'w'); //ファイル作成
            
            $columns = [ //1行目の情報
                'reserved_date',
                'checkin_date',
                'total_price',
            ];

            mb_convert_variables('SJIS-win', 'UTF-8', $columns); //文字化け対策
    
            fputcsv($createCsvFile, $columns); //1行目の情報を追記

            $bookingCurve = DB::table('csvimport');  // データベースのテーブルを指定

            $bookingCurveResults = $bookingCurve  //データベースからデータ取得
                ->select(['reserved_date'
                , 'checkin_date' 
                ,DB::raw('sum(total_price) as total_price')])
                ->groupby('reserved_date')
                ->get();
        
            foreach ($bookingCurveResults as $row) {  //データを1行ずつ回す
                $csv = [
                    $row->reserved_date,  //オブジェクトなので -> で取得
                    $row->checkin_date,
                    $row->total_price,
                ];

                mb_convert_variables('SJIS-win', 'UTF-8', $csv); //文字化け対策

                fputcsv($createCsvFile, $csv); //ファイルに追記する
            }
            fclose($createCsvFile); //ファイル閉じる
        };
        
        return response()->stream($callback, 200, $headers); //ここで実行
        
    }

大事な箇所を解説してみます。

PHPでCSVエクスポートの方法 ポイント1 response->stream

『laravel』でCSVエクスポートする方法をググっていたら、
こんなコメントを見つけたんですね。

CJxD
Newer versions of Laravel removed the Response::stream() function. Instead, use response()->stream($callback, 200, $headers); –
CJxD
直訳:新しいバージョンのlaravelはResponse::stream() を消したので、代わりにresponse()->stream($callback, 200, $headers);を使うといいよ。

参照記事:CSV export in laravel 5 controller

アオキ
そうなんや、ならさっそく取り入れてみよ。

と取り入れつつ、いくつかググって実現できました。

return response()->stream($callback, 200, $headers);

streamの中に、
コールバック(関数、今回はCSVエクスポートする処理)と、
ヘッダ情報を指定しています。

まずはヘッダから。

Sponsored link

PHPでCSVエクスポートの方法 ポイント2 HTTPヘッダ

インターネットを通じてやりとりする時は必ず、

『HTTP(エイチティーティーピー)』というルールにしたがう必要があります。

HTTP・・Hyper Text Transfer Protocol(ハイパーテキストトランスファープロトコル)

『プロトコル』というのが協定とか、決まりみたいな意味です。

で、

HTTPというルールでは必ず、『HTTPヘッダ』をつける決まりになってます。

このページがどんな種類で、どんな設定になってて・・

といった情報をまとめたのが、『HTTPヘッダ』になります。

今回の『HTTPヘッダ』はこんな感じです。

        $headers = [
            'Content-type' => 'text/csv',  //CSV形式ですよー
            'Content-Disposition' => 'attachment; filename=csvexport.csv', //添付ファイルありますよー、ファイル名は***.csvですよー
            'Pragma' => 'no-cache', //キャッシュ(情報保存)しないですよー
            'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0', //キャッシュ期限切れなら確認してやー
            'Expires' => '0', //キャッシュの有効期限は0ですよー
        ];

『キャッシュ』・・一度開いたWebページのデータを保存して、次回アクセス時にさくっと表示できる仕組み

『キャッシュ』を保存するようにすると、
次回アクセス時に読み込むスピードが早くなったりするメリットはあるんですが、
CSVエクスポートに関して言えば、キャッシュは保存しなくていいのかなと思います。

参考記事
『Webを支える技術』 第9章 HTTPヘッダ まとめメモ

次に、return response()->stream($callback, 200, $headers);

の中の、$callback の中で書かれている処理のポイントを。

PHPでCSVエクスポートの方法 ポイント3 お決まりの関数達

「PHP CSV エクスポート」でググるとかなりのサイトで
これらの関数が使われています。

fopen('php://output', 'w');  //ファイルを作成する 直接ブラウザに返す 書きこめる状態で
fputcsv($createCsvFile, $csv); //ファイルに追記する
fclose($createCsvFile);  //ファイルを閉じる

ファイル開いて、
データ追記して、
ファイル閉じて。

アオキ
ここはセットで覚えておくといいんでしょうね。
Sponsored link

PHPでCSVエクスポートの方法 ポイント4 文字化け対策

文字化けに関しては、

WindowsとMacで設定が違うんですが、今回はWindowsを対象に。

WindowsでCSVを開く時はエクセルを使うことが多く、

エクセルは文字コードが『SJIS(エスジス)』になっているので、『SJIS』に合わせないと文字化けしてしまいます。

PHPでは mb_convert_variables という関数を使って文字コードを変更できるので、

1行ずつ文字コードを『UTF-8』から『SJIS』に変更するようにしています。

mb_convert_variables('SJIS-win', 'UTF-8', $columns); //文字化け対策
mb_convert_variables('SJIS-win', 'UTF-8', $csv); //文字化け対策

PHPでCSVエクスポートの方法 ポイント5 forechで繰り返す

データベースからデータを取得して、
foreachで1行ずつCSVファイルに追記していきます。

100行なら100回。
1000行なら1000回繰り返します。

    foreach ($bookingCurveResults as $row) { 
                $csv = [
                    $row->reserved_date,
                    $row->checkin_date,
                    $row->total_price,
                ];

データベースのデータをとってくる際は『オブジェクト型』になっているので -> で指定する必要あります。

参考記事

これらを踏まえてもう一回コードを。

    public function export(Request $request)
    {
        $headers = [ //ヘッダー情報
            'Content-type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename=csvexport.csv',
            'Pragma' => 'no-cache',
            'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
            'Expires' => '0',
        ];

        $callback = function() 
        {
            
            $createCsvFile = fopen('php://output', 'w'); //ファイル作成
            
            $columns = [ //1行目の情報
                'reserved_date',
                'checkin_date',
                'total_price',
            ];

            mb_convert_variables('SJIS-win', 'UTF-8', $columns); //文字化け対策
    
            fputcsv($createCsvFile, $columns); //1行目の情報を追記

            $bookingCurve = DB::table('csvimport');  // データベースのテーブルを指定

            $bookingCurveResults = $bookingCurve  //データベースからデータ取得
                ->select(['reserved_date'
                , 'checkin_date' 
                ,DB::raw('sum(total_price) as total_price')])
                ->groupby('reserved_date')
                ->get();
        
            foreach ($bookingCurveResults as $row) {  //データを1行ずつ回す
                $csv = [
                    $row->reserved_date,  //オブジェクトなので -> で取得
                    $row->checkin_date,
                    $row->total_price,
                ];

                mb_convert_variables('SJIS-win', 'UTF-8', $csv); //文字化け対策

                fputcsv($createCsvFile, $csv); //ファイルに追記する
            }
            fclose($createCsvFile); //ファイル閉じる
        };
        
        return response()->stream($callback, 200, $headers); //ここで実行
        
    }
アオキ
一行一行全部意味があるんですよねぇ、プログラミングって奥が深い・・
Sponsored link

さいごに

仕事で使うWEBサイトやWEBページでは、

必ずと言っていいほど『CSVエクスポート(ダウンロード)』の要望があります。

CSV機能ほしい人
え?なんでCSVでダウンロードできないの?

的な。

そんな時のために、

  1. responseとstream
  2. ヘッダ情報追加する
  3. よく使う関数(fopen, fputcsv, fclose)を知っておく
  4. 文字化け対策
  5. foreachで回す

といった流れをざっくりでも把握しておくと、いざって時にさくっと作れるかもですね。

アオキ
CSVなんだかんだ便利なんですよねー、エクセルでも加工しやすいし、資料とかつくりやすいし。

参考記事

laravel5.3 CSVダウンロードを実装する(あしたからがんばるさん)

Laravel5.4で、CSVダウンロード(一言多いプログラマーの独り言)

追記 2019/1/22
Laravel5.5にアップデート後 実行したらなぜかエラー。

いくつかぐぐると、config/database.php 内の strict が true になっていることが原因のようで、

falseに変更するとOKになりました。

いずれ原因解明したいところです。
QueryBuilderでgroupByをするとSyntax error or access violationがでる件

『PHP(Laravel)』ではこんな記事も読まれています。

1. 【PHP/Laravel】初心者向けの動画をリリースしました【Udemy】

2. 【Laravel(PHP)】初心者向け アプリのつくり方 をリリースしました【techpit】

3. 【PHP】【Laravel】CSVエクスポートの方法〜5つのポイント〜

4. 【PHP】オブジェクトと連想配列の違いについて調べてみた【初心者向け】

5. 【PHP】CSVインポートの方法〜大量データもバルクインサートでバッチリ!〜【laravel】

6. 【PHP】【図解】クラスと抽象クラスとインターフェースとトレイトとDIをまとめてみた【初心者向け】

7. 【PHP】配列や連想配列が覚えづらかったので学校に例えてみた【初心者向け】

8. 【PHP】ホームページに天気予報を表示させる方法【Webスクレイピング】【初心者向け】

9. 【Laravel】Webアプリ環境構築の仕方【Vue.js】【初心者向け】

10. 【PHP】2次元(多次元)配列でデータ取得したいならarray_columnがめっさ便利

アオキ
ツイッターでも記事ネタ含めちょろちょろ書いていくので、よろしければぜひフォローお願いしますm(_ _ )m

アオキのツイッターアカウント


関連記事一覧 (一部広告あり)

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

CAPTCHA


最近の記事

アーカイブ

  1. 生成AI

    Dify講座をリリースしました【非エンジニア向け】
  2. オンライン教材

    【AWS】【初心者向け】インフラの基礎からわかる講座をリリースしました【Udem…
  3. オンライン教材

    【ChatGPT】エンジニア編をリリースしました
  4. データベース

    MySQLの講座をリリースしました
  5. 生成AI

    2024/5/14 OpenAI発表 まとめ
PAGE TOP
Ads Blocker Image Powered by Code Help Pro

広告ブロックを摘出しました!!

ブラウザ拡張を使用して広告をブロックしていることが摘出されました。

ブラウザの広告ブロッカーの機能を無効にするか、
当サイトのドメインをホワイトリストに追加し、「更新」をクリックして下さい。

あなたが広告をブロックする権利があるように、
当方も広告をブロックしている人にコンテンツを提供しない権利と自由があります。

Powered By
Best Wordpress Adblock Detecting Plugin | CHP Adblock