概要
PHPでCSVを出力しました。ハマりどころやサンプルなどを書いてみます
ちょっとハマったとこ
1行目が改行される
なんだかわからないけど、最初の1行目が改行されていました。
ob_clean();を最初に入れてあげることで解決しました。
IDなどの先頭の0が消える
エクセルで見たときに頭に0が入っているデータの0が消えていました。
=”000001″ みたいな感じで囲んで式にしてあげるといいです。
エクセルで開いたときに文字化けする
SJISじゃないと文字化けするようなので、変換しましょう。
サンプル
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$mode = $_POST["mode"]; | |
// ヘッダ行 | |
$head = ['id', '名前', '説明', '価格']; | |
// データ行 | |
$data = [ | |
["00001", 'りんご', '12個です', '1,200'], | |
["00002", 'ぶどう', 'ひとつぶです', '10,200'], | |
["00003", 'なし', '1個です', '120'] | |
]; | |
// 出力モードの場合 | |
if ($mode == "output") { | |
$date = date("Ymd"); | |
header("Content-Type: application/octet-stream"); | |
header("Content-Disposition: attachment; filename=商品リスト_{$date}.csv"); | |
// ヘッダ行の文字コード変換 | |
foreach ($head as $key => $value) { | |
$head[$key] = mb_convert_encoding($value, "SJIS", "UTF-8"); | |
} | |
// データ行の文字コード変換・加工 | |
foreach ($data as $data_key => $line) { | |
foreach ($line as $line_key => $value) { | |
// 0をエクセルで表示させたい | |
if ($line_key == 0) { | |
$value = '="' . $value . '"'; | |
} | |
// , があったらダブルクォーテーションで囲む | |
if (strpos($value, ',')) { | |
$data[$data_key][$line_key] = mb_convert_encoding('"' . $value . '"', "SJIS", "UTF-8"); | |
} else { | |
$data[$data_key][$line_key] = mb_convert_encoding($value, "SJIS", "UTF-8"); | |
} | |
} | |
} | |
echo implode($head, ",") . "\r\n"; | |
foreach ($data as $key => $line) { | |
echo implode($line, ",") . "\r\n"; | |
} | |
exit; | |
} | |
?> | |
<html lang="ja"> | |
<head> | |
<title>くだもの一覧</title> | |
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" | |
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> | |
</head> | |
<body> | |
<form action="./index.php" method="POST"> | |
<div class="container"> | |
<table class="table table-hover table-striped mt-5"> | |
<tr> | |
<?php | |
foreach ($head as $value) { | |
echo "<th>" . $value . "</th>"; | |
} | |
?> | |
</tr> | |
<?php | |
foreach ($data as $line) { | |
echo "<tr>"; | |
foreach ($line as $value) { | |
echo "<td>" . $value . "</td>"; | |
} | |
echo "</tr>"; | |
} | |
?> | |
</table> | |
<input type="hidden" name="mode" value="output"/> | |
<input type="submit" value="出力" class="btn btn-primary pl-3 pr-3"/> | |
</div> | |
</form> | |
</body> | |
</html> |
解説
くだもの一覧という一覧をテキトーに作ってみました。
出力ボタンをおしたらhidden値のmodeが飛んで、CSV出力されます。
header
で出力形式をapplication/octet-streamにしてダウンロードしてくるように設定しています。
それぞれのデータを加工・文字コード変換して、あとはechoで出力してあげるという形にしています。
コメント