Edited at

CakePHPのCsvView プラグインでお手軽CSV出力

More than 1 year has passed since last update.

公式

https://github.com/FriendsOfCake/cakephp-csvview

以下の説明はほぼ公式のドキュメントと内容は同じです。

以下の内容はは


  • CakePHP 3.3

  • CsvView 3.2

の場合です。


主な機能


  • 配列からCSV出力

  • QueryからCSV出力

  • ヘッダー、フッタを指定化

  • CSV文字コードの指定


インストールと有効化

インストール

composer require friendsofcake/cakephp-csvview:~3.0

インストール後、config/bootstrap.phpへプラグイン読み込みを追加


config/bootstrap.php

Plugin::load('CsvView');



動作確認

以下のコードをControllerに書いて確認

public function export()

{
$data = [
['a', 'b', 'c'],
[1, 2, 3],
['あなた', 'と', 'わたし'],
];
$_serialize = ['data'];

$this->viewBuilder()->className('CsvView.Csv');
$this->set(compact('data','_serialize'));
}

以下が表示されるはずです。ちなみに、CsvView.CSvのところをJsonに変える結果がjsonになります。

a,b,c

1,2,3
あなた,と,わたし

まとめると


  • $_serialize にデータの変数名を指定

  • viewBuilder()で`CSvView.CSVを指定

  • $this->setで$data$_serialize をビューに渡す

でCSVが出力できます。

また、データは複数指定する事ができ、以下のコードは同じ結果になります。

public function export()

{
$data = [['a', 'b', 'c']];
$data_two = [[1, 2, 3]];
$data_three = [['あなた', 'と', 'わたし']];

$_serialize = ['data', 'data_two', 'data_three'];

$this->viewBuilder()->className('CsvView.Csv');
$this->set(compact('data', 'data_two', 'data_three', '_serialize'));
}


ヘッダとフッター

ヘッダとフッターをつけるには、_header_footerに配列でセットします。

public function export()

{
$data = [
['a', 'b', 'c'],
[1, 2, 3],
['あなた', 'と', 'わたし'],
];
$_serialize = ['data'];
$_header = ['Column 1', 'Column 2', 'Column 3'];
$_footer = ['Totals', '400', '$3000'];

$this->viewBuilder()->className('CsvView.Csv');
$this->set(compact('data','_serialize', '_header', '_footer'));
}

"Column 1","Column 2","Column 3"

a,b,c
1,2,3
あなた,と,わたし
Totals,400,$3000


ファイルでのダウンロード

大抵はCSVが画面に表示されてもあまり嬉しくなく、ファイルにダウンロードしたいと思います。以下のコードに変更します。

public function export()

{
$data = [
['a', 'b', 'c'],
[1, 2, 3],
['あなた', 'と', 'わたし'],
];
$_serialize = ['data'];
$_header = ['Column 1', 'Column 2', 'Column 3'];
$_footer = ['Totals', '400', '$3000'];

/**
* Windows対応
*/

$_csvEncoding = 'CP932';
$_newline = "\r\n";
$_eol = "\r\n";

$this->response->download('my_file.csv');
$this->viewBuilder()->className('CsvView.Csv');
$this->set(compact('data', '_serialize', '_header', '_footer', '_csvEncoding', '_newline', '_eol'));
}

$this->response->download('my_file.csv') でブラウザにダウンロードを指定します。

また、大抵はExcelで開きたいと言う要望がありますので、文字コードをWindows-SJIS、改行をCRLFに変更します。


  • _csvEncoding : CSV文字の文字コード。iconvで変換。CP932がWindowsの文字コード


DBから直接CSV出力

Postsテーブルの内容から直接CSVを出力する場合。

public function export()

{
$posts = $this->Posts->find('all');
$_serialize = 'posts';
$_header = ['Post ID', 'Title', 'Created'];
$_extract = [
'id',
function ($row) {
return $row['title'];
},
'created'
];

$this->viewBuilder()->className('CsvView.Csv');
$this->set(compact('posts', '_serialize', '_header', '_extract'));
}

_serializeにQuery、_extractに出力したいカラム名を指定すれば、Queryが実行されCSVが出力されます。

_extractは CakePHPの Hash::extract()を利用しており、callableを利用できるので値を編集できます。


複雑なCSVを出力する

_serializeにnull を指定すると、templateを利用して自前でCSVを出力できます。

以下の場合、テンプレートはcsvディレクトリにあるものが指定され、 src/Template/Posts/csv/export.ctpになります。


src/Controller/PostsController.php

public function export()

{
$posts = $this->Post->find('all');
$_serialize = null;
$this->viewBuilder()->className('CsvView.Csv');
$this->set(compact('posts', '_serialize'));
}

以下のように、CSVのデータ部分のみを出力するTemplateを作成します。


src/Template/Posts/csv/export.ctp


foreach ($posts as $post) {
echo $post->id . ',' . $post->title . ',' . $post->created . PHP_EOL;
}


CSV制御オプション

CSVの出力を変更するのに、以下の変数が利用できます。

変数名
デフォルト
説明

_delimiter
','
データ区切り文字

_enclosure
'"'
データのクオート文字

_eol
"\n"
データ改行文字

_newline
"\n"
新規行

_bom
false
BOMを出力するか

_null
''
データがnullの表示値

_dataEncoding
'UTF-8'
データの文字コード。iconvを利用

_csvEncoding
'UTF-8'
csv表示の文字コード。iconvを利用