PHP로 배열을 CSV 출력

8865 단어 CSVPHP

계기



업무로 DB의 데이터를 csv 출력하고 싶은 요건으로부터 구현
앞으로도 필요하게 된다고 생각했기 때문에 정리했습니다.

이번 내용



csv로 출력한 데이터를 버튼을 누르면 다운로드

이런 느낌


php로 csv 출력할 때 fputcsv関数SplFileObjectクラス 를 사용하는 방법이 있는 것 같습니다만, 이번은 fputcsv関数 를 사용했습니다.
이 함수나 클래스를 사용하지 않아도 실현은 가능

csv란?



"CSV"는 "Comma Separated Value"의 약자로 데이터를 쉼표(",")로 구분한 값입니다. 응용 프로그램간에 데이터를 교환하는 데 사용됩니다. CSV 형식으로 저장된 파일을 "CSV 파일"이라고 합니다.

Excel과의 차이는 Excel은 문자에 색이나 테두리라든지 데이터에 장식 가능합니다만, csv는 단지 텍스트로 구성된 데이터 같습니다.
추가 정보가 없으므로 응용 프로그램간에 텍스트 데이터를 교환할 수 있습니다.

막상 구현


  • 출력하고 싶은 데이터
  • $user = array(
        array(
            'id' => 1,
            'name' => 'Aさん',
            'email' => '[email protected]',
            'password' => 'aaaaa'
        ),
        array(
            'id' => 2,
            'name' => 'Bさん',
            'email' => '[email protected]',
            'password' => 'bbbbb'
        ),
        array(
            'id' => 3,
            'name' => 'Cさん',
            'email' => '[email protected]',
            'password' => 'ccccc'
        ),
    );
    

    ※이런 데이터를 DB로부터 가져와서 배열에 넣는다.

  • 다운로드 버튼 표시
  • <h1>Hello World!<h1>
    <a href="./csv.php">
        <button>csvダウンロード</button>
    </a>
    



  • csv 출력 and 다운로드 처리
  • 
    $user =[配列]
    
    function putCsv($data) {
    
        try {
    
            //CSV形式で情報をファイルに出力のための準備
            $csvFileName = '/tmp/' . time() . rand() . '.csv';
            $fileName = time() . rand() . '.csv';
            $res = fopen($csvFileName, 'w');
            if ($res === FALSE) {
                throw new Exception('ファイルの書き込みに失敗しました。');
            }
    
            // 項目名先に出力
            $header = ["id", "name", "email", "password"];
            fputcsv($res, $header);
    
            // ループしながら出力
            foreach($data as $dataInfo) {
                // 文字コード変換。エクセルで開けるようにする
                mb_convert_variables('SJIS', 'UTF-8', $dataInfo);
    
                // ファイルに書き出しをする
                fputcsv($res, $dataInfo);
            }
    
            // ファイルを閉じる
            fclose($res);
    
            // ダウンロード開始
    
            // ファイルタイプ(csv)
            header('Content-Type: application/octet-stream');
    
            // ファイル名
            header('Content-Disposition: attachment; filename=' . $fileName); 
            // ファイルのサイズ ダウンロードの進捗状況が表示
            header('Content-Length: ' . filesize($csvFileName)); 
            header('Content-Transfer-Encoding: binary');
            // ファイルを出力する
            readfile($csvFileName);
    
        } catch(Exception $e) {
    
            // 例外処理をここに書きます
            echo $e->getMessage();
    
        }
    }
    
    putCsv($user);
    

    ※추기( @rana_kualu 님의 코멘트를 받아)



    위의 방법으로 출력하기 위해 만든 $csvFileName 파일이/tmp/에 남아 있습니다.
  • 파일을 출력한 후 unlink에서 파일을 삭제합니다.

  • tmpfile 에서 자동으로 임시 파일을 삭제합니다.
  • fopenfilenamephp://output 을 지정하여 임시 파일을 만들지 않고 csv 출력한다.

  • 임시 파일

    ■fopen 함수로 출력하는 파일을 지정해 열
    두 번째 인수에 w를 지정하여 쓰기 모드로 만듭니다.

    ■ fputcsv 함수로 위에서 열린 파일에 csv를 출력한다
    foreach로 돌리기 전에 헤더가 되는 부분을 출력한다.
    그 후 foreach로 배열을 돌려 출력한다.

    ■ 다운로드를 위한 HTTP 헤더 설정Content-Type 아래에서 php의 출력 형식을 지정한다.
    이번에는 csv 파일로 출력하는 지정을 하고 있으므로, 브라우저에서 열람할 수 있는 페이지로서는 출력되지 않는다.

    출력 결과



    mb_convert_variables('SJIS', 'UTF-8', $dataInfo); 로 문자 코드를 변환하고 있기 때문에 일본어 부분의 「씨」가 제대로 표시되고 있다.
    이것이 없으면 Excel에서 열 때 문자가 깨져 버린다.

    이상

    좋은 웹페이지 즐겨찾기