クライアントから一覧ページをCSVでダウンロードできるようにしてほしいという依頼があったので、データを投げるとCSVを生成してダウンロードしてくれるクラスを作りました。
Contents
CsvUtilクラス
createCsvメソッドにファイル名、ヘッダ、レコードを投げると、CSVを作成しダウンロードしてくれます。
<?php
class CsvUtil
{
public static function createCsv($filename,$header,$records)
{
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$filename.csv");
//ファイルを開く
$stream = fopen('php://output', 'w');
//ヘッダーを書き込み
fputcsv($stream, $header);
//レコードを書き込み
foreach($records as $record){
fputcsv($stream, $record);
}
exit();
}
}
使い方
ここでは静的なデータを渡しておりますが、実際は動的なデータになることがほとんどなのではないかと思います。
今回自分はModelで取得した値をControllerで整形して、createCsvに渡すという風にしましたがここでは割愛します。
<?php
require "./CsvUtil.php";
$fileName = "test";
$header = array(
"カラム1",
"カラム2",
"カラム3",
);
$records = array(
array("1行目1列目","1行目2列目","1行目3列目"),
array("2行目1列目","2行目2列目","2行目3列目"),
array("3行目1列目","3行目2列目","3行目3列目"),
);
CsvUtil::createCsv($filename, $header, $records);
ダウンロードされたファイルを開くとこのようになっています。
文字化けに関して
PHPの文字コードがデフォルトでUTF-8らしく、ダウンロードされたCSVをSJISで開こうとすると(例えば、Excelで開こうとすると)、日本語の文字化けが起こると思います。SJISで開くことが多い場合は、ヘッダーとレコードに対してmb_convert_variablesをしてやると解決すると思います。
<?php
mb_convert_variables('SJIS','UTF-8',$header);
mb_convert_variables('SJIS','UTF-8',$records);
ソースコード全文
最後にソースコードを全文載せておきます。
<?php
class CsvUtil
{
public static function createCsv($filename,$header,$records)
{
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$filename.csv");
mb_convert_variables('SJIS','UTF-8',$header); //SJISで開くことが多い場合いれるといいかも
mb_convert_variables('SJIS','UTF-8',$records); //SJISで開くことが多い場合いれるといいかも
//ファイルを開く
$stream = fopen('php://output', 'w');
//ヘッダーを書き込み
fputcsv($stream, $header);
//レコードを書き込み
foreach($records as $record){
fputcsv($stream, $record);
}
exit();
}
}
以上、PHPでCSVを作成してダウンロードする方法でした。
コメント