CakePHP CSV出力してみる

notoです。 CakePHPでCSV出力をさせる機会があったので、備忘録的にメモ。

Helper

まずはCSVヘルパーをこちらからごっそり頂きます。 CSV Helper

以下のソースを「/app/views/helpers/csv.php」として配置します。

/app/views/helpers/csv.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php
/**
 * CSVヘルパー
 *
 */
class CsvHelper extends AppHelper {

    var $delimiter = ',';
    var $enclosure = '"';
    var $filename = 'Export.csv';
    var $line = array();
    var $buffer;

    function CsvHelper() {
        $this->clear();
    }

    function clear() {
        $this->line = array();
        $this->buffer = fopen('php://temp/maxmemory:'. (5*1024*1024), 'r+');
    }

    function addField($value) {
        $this->line[] = $value;
    }

    function endRow() {
        $this->addRow($this->line);
        $this->line = array();
    }

    function addRow($row) {
        fputcsv($this->buffer, $row, $this->delimiter, $this->enclosure);
    }

    function renderHeaders() {
        header("Content-type:application/vnd.ms-excel");
        header("Content-disposition:attachment;filename=".$this->filename);
    }

    function setFilename($filename) {
        $this->filename = $filename;
        if (strtolower(substr($this->filename, -4)) != '.csv') {
            $this->filename .= '.csv';
        }
    }

    function render($outputHeaders = true, $to_encoding = null, $from_encoding = "auto") {
        if ($outputHeaders) {
            if (is_string($outputHeaders)) {
                $this->setFilename($outputHeaders);
            }
            $this->renderHeaders();
        }
        rewind($this->buffer);
        $output = stream_get_contents($this->buffer);
        if ($to_encoding) {
            $output = mb_convert_encoding($output, $to_encoding, $from_encoding);
        }
        return $this->output($output);
    }
}

Controller

先ほど作成したCSVヘルパーを、controllerのhelpersプロパティにセットします。

1
2
3
4
5
6
7
8
9
10
11
<php

/**
* コントローラー
*/
class HogesController extends AppController {

    /**
     * CSVヘルパー
     */
    var $helpers = array( 'Csv' );

downloadアクションを作成し、CSV出力したいデータを生成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function download(){

   //デバッグ出力制御
   Configure::write('debug', 0);

   //csv形式で出力したいデータ
   $lines = array(
      array('noto','test'),
      array('chakemi','test')
   );

   $fileName = date('Ymd');

   $this->set(compact( 'lines' , 'fileName' ));

   //レイアウトなし
   $this->layout = false;
}

View

「app/views/hoges/」配下にdownload.ctpを作成します。

1
2
3
4
5
6
7
8
9
10
<?php
    //controllerから渡されたデータを追加     
    foreach ($lines as $line) {
         $csv->addRow( $line );
    }
    //ファイル名設定
    $csv->setFilename( $fileName );

    //文字コードをUTF-8からSJISに変換して出力。
    echo mb_convert_encoding($csv->render(), 'SJIS', 'UTF-8');

結果

こんな感じでCSV出力されます。

1
2
noto,test
chakemi,test

Comments