PHP データベースの中身をCSVファイルに出力し、ユーザーにダウンロードさせる
データベースのクエリの出力結果をCSVファイルに出力し、ユーザーにダウンロードさせたい場合があると思います。
サンプルコードとして置いておきます。
//POSTで出力したいSQL文を渡す //csv_output_sqlというnameでPOST if ($_POST['csv_output_sql']){ $csv_output_sql=$_POST['csv_output_sql']; $datas = $db->query($csv_output_sql); //ここはDBに接続して、うまくデータを取ってきてください $file = 'test.csv'; file_put_contents($file, $datas); header('Content-Disposition: attachment; filename="'. $file . '"'); header('Content-Type: text/csv;'); //$datasのフィールド名を、CSVの1行目として出力します $field_names=array_keys($datas); $converted_field_names=make_csv_line($field_names); print $converted_field_names;
foreach ($datas as $each_data) { $data= make_csv_line($each_data); //データの文字コード変換が必要な場合、ここで変換します。 //ここではUTF-8からSJISへ変換しています。 $data_converted=mb_convert_encoding($data, "SJIS", "UTF-8"); print $data_converted;
}
//PHP がバイナリデータを誤認識し、コード変換することの無いようにします。
mb_http_output(‘pass’);
} function make_csv_line($values){ foreach($values as $i =>$value){ if ((strpos($value, ',') !== false) || (strpos($value, '"') !== false) || (strpos($value, ' ') !== false) || (strpos($value, "\t") !== false) || (strpos($value, "\n") !== false) || (strpos($value, "\r") !== false)) { $values[$i] = '"' . str_replace('"', '""', $value) . '"'; } } return implode(',',$values)."\n"; }
function make_csv_line()に関しては、下記のサイトを参考にさせて頂きました。
http://php.find-info.ru/php/006/learnphp5-CHP-10-SECT-4.html
文字化けが発生する場合は
株式会社の㈱などが文字化けする場合
$data_converted=mb_convert_encoding($data, "SJIS-win", "UTF-8");
と文字コードの変換先をSJIS-winを指定してみてください。
さて、もう一歩進んで、こういう場合に頭が痛いのがデータベースには日付がエポックタイムスタンプで入っている場合です。
エポックタイムスタンプで出力しても、CSVではうまく表示されませんし、ユーザーには何のことかわかりませんよね。
日付のフィールドだけPOSTで飛ばせば日付をエポックタイムスタンプから日付へ変換するようにしておきます。
日付のフィールドが複数あることを想定しています。
//日付の項目がPOSTされていれば、日付をエポックタイムスタンプから日付へ変換 //convert_date_fieldというnameで日付にしたいフィールド名をPOST if ($_POST['convert_date_field']){ $convert_date_fields=$_POST['convert_date_field']; foreach($convert_date_fields as $convert_date_field){ $datas->fields[$convert_date_field]=strftime('%y/%m/%d',$datas->fields[$convert_date_field]); } }
上記のループをforeach文の中に入れておけば、エポックタイムスタンプを通常のユーザーが見てわかる日付になります。
*エラーが表示される場合
Warning: file_put_contents : failed to open stream: Permission denied in
というような文字列が表示される場合は、ディレクトリのパーミッションを、書き込みが可能なように変更してください。
適宜カスタマイズして使ってください。