業務系システムでは、ユーザーの業務効率化やデータの共有を支援するために、データの書き出し(エクスポート)機能が重要な役割を果たします。その中でも、CSV形式でのエクスポートは特に広く利用されています。なぜなら、CSVは汎用的なフォーマットであり、Microsoft ExcelやGoogleスプレッドシートなど、さまざまなツールで容易に開けるからです。
今回は、PHPを使ってデータをCSV形式でエクスポートする方法を解説します。この例では、基本的な実装の流れから、ブラウザを介したファイルダウンロードまでをカバーします。
1.準備
CSVエクスポート機能を実装するためには、以下の条件を満たす必要があります。
<前提条件>
- FTPソフトの使用環境が整っていること
PHPコードをサーバーにアップロードするためには、FTPソフトが必要です。たとえば、「FileZilla」や「WinSCP」のようなFTPクライアントを使用すれば、簡単にサーバー上にファイルを作成・編集できます。 - サーバーがPHPをサポートしていること
CSVエクスポート処理はPHPスクリプトで実行されるため、PHPが利用可能な環境が必要です。 - ブラウザでファイルをダウンロード可能な設定が有効であること
HTTPレスポンスで適切なヘッダーを設定することで、ブラウザがダウンロードをトリガーします。
2.ダウンロードフォームの作成
まず、ユーザーがダウンロードを実行するためのフォームを用意します。このフォームには、ダウンロード用のボタンを配置し、そのボタンからPHPスクリプトを呼び出します。
HTMLコード例
以下のコードを使用して、シンプルなダウンロードボタンを設置します。
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<title>【PHP】CSVエクスポート(デモ用)</title>
</head>
<body>
<h2>【PHP】CSVエクスポート(デモ用)</h2>
<a href="./export.php">
<button type="button">CSVダウンロード</button>
</a>
</body>
</html>
ポイント
- ボタンをクリックすると、
export.php
スクリプトが呼び出されます。 - ユーザーには「CSVダウンロード」という明確なアクションが提示され、シンプルで直感的です。
2.CSVエクスポート機能の実装
CSVファイルを生成し、ブラウザを通じてダウンロードするPHPコードを作成します。
PHPコード例
以下に、export.php
のコードを示します。
<?php
$csv_head = array(
'名前',
'年齢',
'血液型',
);
$list_csv = array(
array("太郎", "31", "O"),
array("次郎", "28", "A"),
array("三郎", "27", "AB"),
array("四郎", "22", "B")
);
ob_start();
$fp = fopen('php://output', 'w');
fwrite($fp, "\xef\xbb\xbf");
fputcsv($fp, $csv_head);
foreach ($list_csv as $key => $val) {
$col = array();
$col[] = $val[0];
$col[] = "=\"" . $val[1] . "\"";
$col[] = $val[2];
fputcsv($fp, $col);
}
$str = ob_get_clean();
fclose($fp);
header('Content-Type: text/csv');
header("Cache-Control: public");
header("Pragma: public");
header('Content-type: application/text charset="UTF-8"');
header("Content-Disposition: attachment; filename=iroha_" . date("YmdHis") . ".csv");
echo $str;
exit;
?>
コードのポイント
- データ構造の定義
$csv_head
にはCSVのヘッダー行を、$list_csv
にはデータ本体を定義しています。 - バッファリングとUTF-8対応
ob_start()
でバッファリングを開始し、BOMを追加して文字化けを防止しています。 - ヘッダーとデータの出力
fputcsv
を使用してデータを1行ずつCSV形式で書き込んでいます。Excelでの文字列処理を意識し、年齢カラムに="31"
形式を適用しています。 - HTTPレスポンスの設定
Content-Type
やContent-Disposition
を設定して、ブラウザが自動的にファイルをダウンロードするようにしています。
プログラムの仕組み
コードの構造と機能
CSVヘッダーとデータの定義:
$csv_head = array(
'名前',
'年齢',
'血液型',
);
$list_csv = array(
array("太郎", "31", "O"),
array("次郎", "28", "A"),
array("三郎", "27", "AB"),
array("四郎", "22", "B")
);
- $csv_head: CSVファイルのヘッダー行を定義しています。名前, 年齢, 血液型 の順です
- $list_csv: CSVファイルに記載するデータを2次元配列で定義しています。各配列の中身は「名前」「年齢」「血液型」です
バッファリングの開始:
ob_start();
$fp = fopen('php://output', 'w');
fwrite($fp, "\xef\xbb\xbf");
- ob_start(): 出力をバッファリングします。つまり、生成された出力を一時的に保持して、後でまとめて処理します
- fopen(‘php://output’, ‘w’): 特殊な出力ストリームphp://outputを開き、書き込みモードで利用しています。このストリームに書き込むと、HTTPレスポンスに直接出力できます
- fwrite($fp, “\xef\xbb\xbf”): ファイルの先頭にBOM (Byte Order Mark) を書き込んでいます。これにより、生成されるCSVがUTF-8エンコードであることを明示します
ヘッダーとデータの書き込み:
fputcsv($fp, $csv_head);
foreach ($list_csv as $key => $val) {
$col = array();
$col[] = $val[0];
$col[] = "=\"" . $val[1] . "\"";
$col[] = $val[2];
fputcsv($fp, $col);
}
- fputcsv($fp, $csv_head): ヘッダー行(名前, 年齢, 血液型)をCSV形式で出力します
- foreachループ:
- $list_csv内の各データ(名前・年齢・血液型)を1行ずつ取り出します
- 年齢のカラムは、=”31″のようにExcel形式で出力されます。この形式を使うと、数字が文字列として認識されます
- fputcsv: 配列をCSV形式に変換し、出力ストリームに書き込むPHP関数です
出力とファイルのクローズ:
$str = ob_get_clean();
fclose($fp);
- ob_get_clean(): バッファリングされた内容を文字列として取得し、バッファをクリアします
- fclose($fp): ストリームを閉じます
HTTPレスポンスヘッダーとダウンロード:
header('Content-Type: text/csv');
header("Cache-Control: public");
header("Pragma: public");
header('Content-type: application/text charset="UTF-8"');
header("Content-Disposition: attachment; filename=iroha_" . date("YmdHis") . ".csv");
echo $str;
exit;
- HTTPヘッダーの設定:
- Content-Type: MIMEタイプをtext/csvに設定し、CSVファイルであることを指定。
- Cache-Control / Pragma: ブラウザキャッシュ制御。
- Content-Disposition: ファイル名を指定し、ダウンロードを強制する。
echo $str
: バッファリングされたCSVデータを出力しますexit
: スクリプトの実行を終了します
動作の流れ
- PHPスクリプトにアクセスすると、ヘッダーとデータを含むCSVファイルが生成される
- HTTPレスポンスとして、生成されたCSVファイルが送信される
- ブラウザはダウンロードダイアログを表示し、ユーザーはファイルを保存できる
注意点
- Excel対応
数値カラムを文字列として扱う形式(="31"
)にすることで、Excelでデータが正しく表示されます。 - 文字化け防止
UTF-8のBOMを追加することで、日本語を含むデータが文字化けせずに表示されます。 - セキュリティ
適切なキャッシュ制御(Cache-Control
とPragma
)を設定し、不要なデータの公開を防ぎます。 - ファイル命名規則
動的にファイル名を設定(例:iroha_YYYYMMDDHHMMSS.csv
)することで、ダウンロード時にファイルが上書きされないようにしています。
デモ
デモの不具合や質問等の連絡はお問い合わせページからお願いします。