CSV

CSVについて

歴史 / ルール / サンプル / エクスポート / インポート(HTML+CSS+JS+PHP)

CSVの歴史(ざっくり)

“Comma-Separated Values” は「表データをテキストでやりとりする」実務の都合から広まった形式です。

  • 表計算・データ交換の現場で、アプリやOSをまたいで扱える“最低限の共通形式”として定着。
  • 仕様が1枚岩ではないのが特徴(同じCSVでも、区切りがカンマ/タブ/セミコロン、改行やクォートの扱いが微妙に違う)。
  • 後に相互運用のための整理として、慣習やRFC(例:RFC 4180)が参照されるようになったが、現実は「相手のCSVに合わせる」が多い。
現場あるある: 「Excelで開くと文字化け」「カンマ入りの住所が列ズレ」「改行入りセルで地獄」 → だからこそ ルール(クォート/文字コード/改行)を押さえるのが重要。

CSVの基本ルール

“だいたいこう” の共通点と、事故りやすいポイント。

1) 区切り文字(delimiter)

  • 一般的には カンマ(,)。地域や環境によって セミコロン(;)タブ(TSV) も多い。

2) 1行=1レコード、改行=行区切り

  • 改行コードは LF または CRLF。混在するとツール次第で崩れます。

3) ダブルクォート(")の扱い

  • 値の中に カンマ / 改行 / ダブルクォート が含まれる場合、フィールド全体を "で囲うのが定番。
  • 値の中のダブルクォートは ""(2つ) にしてエスケープする。
例:カンマ入り
name,address
Alice,"Tokyo, Japan"
例:ダブルクォート入り
text
"He said ""Hello""."

4) 文字コード(超重要)

  • Webや多くのシステムは UTF-8 が基本。
  • Excelでの文字化け対策として、UTF-8に BOM を付ける運用がよくあります(このページのDL/ExportはBOM付き)。
  • 相手が Shift_JIS(CP932) を要求するケースもあるので、要件に合わせて変換。
CSVは“ゆるい”形式: 「ルールを守ったCSV」より「相手が読めるCSV」が正解になりがち。 受け入れ側は 区切り推定・BOM除去・列数揃え など防御が大事。

サンプルCSV

このページ配下の ./data/lesson/ に置いてあるサンプルをダウンロードできます。

sample_people.csv(中身)
id,name,email,note
1,Alice,alice@example.com,"Tokyo, Japan"
2,Bob,bob@example.com,"He said ""Hello""."
3,Carol,carol@example.com,"改行入りの例:1行目
2行目(CSVとしては同一セル扱い)"
sample_products.csv(中身)
sku,title,price,tag,description
P-001,USB-C Cable,980,accessory,"1m / 60W / ""fast"""
P-002,Wireless Mouse,2480,device,"Silent click, 2.4GHz"
P-003,Notebook,350,stationery,"A5, ruled, made in Japan"

CSVのエクスポート(PHP例)

配列やDB結果をCSVとして出力してダウンロードさせる基本形。

ポイント:

  • Content-TypeContent-Disposition を指定
  • Excel向けに UTF-8 BOM を付ける運用も多い
  • 値は fputcsv を使う(クォート/エスケープを任せられる)
<?php
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="export.csv"');

// Excel対策でBOM(不要なら削除)
echo "\xEF\xBB\xBF";

$out = fopen('php://output', 'w');

// ヘッダー
fputcsv($out, ['id','name','note']);

// データ(例)
$rows = [
  [1, 'Alice', 'Tokyo, Japan'],
  [2, 'Bob', "He said \"Hello\"."],
];

foreach ($rows as $r) {
  fputcsv($out, $r);
}
fclose($out);
exit;
?>

CSVのインポート(アップロード→プレビュー)

CSVを受け取り、区切り推定・BOM除去・列数揃えをしつつ最大50行プレビューします。

※ 文字コードがShift_JISの場合、環境によっては化けます。必要ならUTF-8へ変換してから試してください。

DBに保存する時の考え方(例)
  • ヘッダー名でマッピング(例:email列→users.email)
  • バリデーション(必須、文字数、型、重複)
  • トランザクションで一括投入、失敗時ロールバック
  • ログを残す(何行成功/失敗、失敗理由)
補足
  • CSVは“仕様がゆるい”ので、受け取り側は防御的に作るのがコツ。
  • Excel互換が必要なら、UTF-8 BOM or Shift_JIS を要件で決める。
  • 巨大CSVはストリーム処理(1行ずつ)+バッチ投入が安全。
ファイル
  • ./data/lesson/ … サンプルCSV
  • ./assets/css/styles.css … デザイン
  • ./assets/js/main.js … UI(コピー/タブ/ファイル名表示)