Laravel CSVダウンロード機能の実装

# はじめに
実務で、CSVダウンロード機能の実装を行いましたので、備忘録として残します。

# CSVダウンロード機能の実装
例として、ユーザー情報をCSVで出力するとします。

まず、実装コードとしては、以下になります。
後ほど、それぞれ解説いたします。

````php
    $users = User::get();
    
    $csvHeader = [
        'ID','姓','名','姓カナ','名カナ','メールアドレス','性別','生年月日','年齢'
    ];
    $temps = [];
    array_push($temps, $csvHeader);

    foreach ($users as $user) {
        $temp = [
            $user->id,
            $user->name1,
            $user->name2,
            $user->name_kana1,
            $user->name_kana2,
            $user->email,
            $user->sex,
            $user->age,
            ];
            array_push($temps, $temp);
        }
        $stream = fopen('php://temp', 'r+b');
        foreach ($temps as $temp) {
            fputcsv($stream, $temp);
        }
        rewind($stream);
        $csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
        $csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
        $now = new Carbon();
        $filename = "ユーザー一覧（全件：" . $now->format('Y年m月d日'). "）.csv";
        $headers = array(
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename='.$filename,
        );
        return Response::make($csv, 200, $headers);
        
````
# コードの解説
## ①　CSVの項目名作成
````php
  $csvHeader = [
        'ID','姓','名','姓カナ','名カナ','メールアドレス','性別','生年月日','年齢'
    ];
````
CSVの項目名を配列にしています。


## ②　出力したいデータの作成
````php
    $temps = [];
    array_push($temps, $csvHeader);
````
出力したいデータを保存するため、$tempという配列を作成し、先ほど作成した項目名の配列を追加しています。



````php
   foreach ($users as $user) {
        $temp = [
            $user->id,
            $user->name1,
            $user->name2,
            $user->name_kana1,
            $user->name_kana2,
            $user->email,
            $user->sex,
            $user->age,
            ];
            array_push($temps, $temp);
        }
````
また、出力するユーザー情報に関しても、foreachで取り出し、$tempに追加します。

## ③　書き込み用のファイルを一時的に作成し、開く
````php
    $stream = fopen('php://temp', 'r+b');
````
書き込み用のファイルを開くために、fopen関数を使用します。

:::note info
fopen関数とは
ファイルまたは URL をオープンする関数のこと。
第一引数にはファイル名、第二引数にはモードを指定します。

モードはいくつか種類があります。
参考URL: https://www.php.net/manual/ja/function.fopen.php
:::

## ④　作成したファイルに出力したいデータを書き込む
````php
    foreach ($temps as $temp) {
        fputcsv($stream, $temp);
    }
````
foreachで値を取り出し、fputcsv関数を使用して、ファイルにデータを書き込みます。

## ⑤　ファイルポインタを先頭に戻す
````php
    rewind($stream);
````

次に行う操作が、ファイルの先頭から始める必要があるため、rewind()を使用してファイルポインタを先頭に戻します。

## ⑥　改行コードを置き換え・文字列に変換・エンコード
````php
     $csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
````

fputcsvで書き込む際に、1つ書き込むたびに改行コード（PHP_EOL）が追加されています。
この改行コードがOS依存のため、str_replace関数を用いて「\r\n」に置き換えます。

また、stream_get_contents関数を用いて、文字列に変換します。

## ⑦　文字列をエンコードする
````php
    $csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
````
PHPは「UTF-8」で書かれているが、CSVをExcelで開く際に「sjis-win」で開き、文字化けを防ぐため、「sjis-win」にエンコードします。

## ⑧　ファイルをCSV形式に変換する
````php
    $headers = array(
        'Content-Type' => 'text/csv',
        'Content-Disposition' => 'attachment; filename='.$filename,
    );
````

## ⑨　CSVファイルを出力する
````php
    return Response::make($csv, 200, $headers);
````

# さいごに
実装する中で、色々な関数を使用したりして、とても勉強になりました！
この記事が皆さんの参考になりますと幸いです。

最後までお読みいただき、ありがとうございました！
（間違っているとこなどありましたら、ぜひご指摘ください！）