BlueprintLab Deep Guide
CSV完全ガイド――文字化け・列ずれ・Excelの自動変換まで、壊さず扱うための基本
CSVは「Excelの簡易版」ではありません。構造・文字コード・読み込み側の解釈を分けて考えると、トラブルのほとんどは整理できます。
CSVをExcelで開いたら文字化けした。
別のCSVは、文字は読めるのに全部A列に入った。
さらに別のCSVでは、見た目は普通なのに 00123 が 123 になっていた。
同じ「CSVのトラブル」なのに、症状がずいぶん違いますよね。
ここで全部を「CSVが壊れた」でまとめてしまうと、原因探しが急に難しくなります。
実はCSVで起きる問題は、かなり大ざっぱに分けると次の3つです。
- どこで列や行を分けるかという構造の問題
- 文字をどう読むかという文字コードの問題
- 読んだ値を何だと思うかというExcelなど読み込み側の問題
この3つを分けて見ると、「文字化けなのに区切り文字を直していた」「先頭ゼロが消えたのに文字コードを疑っていた」といった遠回りがかなり減ります。
このガイドでは、いま目の前で起きている症状から入りながら、最後にCSV全体の仕組みまでつなげます。
まずCSVをメモ帳で見ると、かなり正体が分かります
CSVをExcelで開くと、きれいな表に見えます。
でも、元のファイルをテキストとして見ると、だいたいこんな感じです。
product_id,name,price
00123,青いマグカップ,1980
00124,"大きい,赤いマグカップ",2480
表っぽく見えないですよね。
基本は、文字が並んでいて、値と値の境目を記号で示しているだけなんです。
1行目は見出し。2行目以降がデータ。ここではカンマが列の境目です。
そして、ここがCSVで最初に知っておくとかなり楽になるところなんですが、CSV自身は 00123 を「商品コード」だとは知りません。
CSVの中にあるのは、基本的には 0 0 1 2 3 という文字です。
「これは数字だから計算できる値だろう」「これは日付っぽいな」と意味を付けるのは、CSVを開いたアプリ側なんです。
CSVは値を運ぶのは得意ですが、その値の意味まではあまり持っていません。
この性質が、CSVの便利さでもあり、事故の入り口でもあります。
文字は読めるのに全部A列なら、まず「区切り」を見ます
例えばExcelで日本語は普通に読めているのに、1行全部がA列に入っている。
この場合、UTF-8やShift_JISを何度切り替えても直らないことがあります。
文字の読み方ではなく、どこで列を切るかが合っていないからです。
CSVという名前なので「カンマ区切りに決まっている」と思いたくなるんですが、実務ではタブやセミコロンを使うファイルもあります。
name,age,city
山田,35,東京
これはカンマ区切り。
name;age;city
山田;35;東京
こちらはセミコロン区切りです。
人間にはすぐ違いが分かりますが、読み込み側がカンマしか探していなければ、セミコロン区切りの1行は「分ける場所がない1つの値」に見えます。
その結果、全部A列です。
Excelなら、CSVをダブルクリックするより [データ]→[テキストまたはCSVから] で開くと、読み込み前のプレビューで区切り文字を変えられます。
文字は読める。でも列にならない。
そのときは、まずここです。
途中の行だけズレるなら、カンマより「引用符」を疑います
全部A列より少し厄介なのが、最初はきれいなのに、ある行だけ列が1つ右へずれるケースです。
よくあるのが、値そのものの中にカンマが入っている場合です。
例えば商品名が Large, Red Mug なら、そのまま書くとこう見えます。
id,name,price
A001,Large, Red Mug,1980
これではカンマが3つあるので、読み込み側には4列に見えます。
そこでCSVでは、カンマを含む値をダブルクォートで囲います。
id,name,price
A001,"Large, Red Mug",1980
外側の " が、「この中のカンマは列の境目ではありません」と伝えてくれるわけです。
さらに、値の中にダブルクォート自体を入れるなら、通常は2つ重ねます。
id,note
A001,"サイズは""Large""です"
ここ、テキストだけ見ると少し変な感じがしますよね。
でもCSVにとっては、この“囲い方”がかなり大事です。
自由記述、住所、商品説明などにカンマや改行が入るCSVで、途中の行だけ急に列ずれするなら、最初に壊れた行の前後で引用符を見てみると原因を見つけやすくなります。
1つのセルの中に改行があっても、正しいCSVにはできます
例えば備考欄が2行だったとします。
id,note,status
A001,"1行目
2行目",ok
テキストエディタではレコードが2行に割れたように見えます。
でも引用符の中にある改行なら、CSVパーサーは1つのフィールドとして扱えます。
ここで単純に「物理的な1行=1レコード」と考えて処理すると壊れます。
CSVが一見単純なのに、手作業の文字列連結で作ると意外と事故が出やすいのはこのためです。
アプリ側でCSVを生成するなら、実績のあるCSVライブラリを使った方が安全です。
日本語が「譁」「縺」みたいになったら、今度は文字コードです
列は分かれている。でも日本語だけ読めない。
この症状なら、区切りより文字コードの方を見ます。
CSVの中で「山田」という文字は、そのまま“山田”として保存されているわけではありません。ファイルの中では、決められたルールに従ってバイト列へ変換されています。
UTF-8で保存したものを、読み込み側がShift_JIS系だと思って読む。
すると同じバイト列を別のルールで文字へ戻すので、見たことのない文字列になります。
ファイルが壊れたように見えるんですが、中身を変更していなくても、読むルールが違うだけで文字化けは起きるんです。
これが分かると、文字化けしたCSVをいきなり作り直す必要がない理由も見えてきます。
まず読み方を変えればいいかもしれません。
UTF-8とShift_JIS、どちらが“正しい”ではなく、読む相手に合っているかです
今のWebやAPIではUTF-8が中心です。
一方、日本の既存業務システムではShift_JIS系のCSVを要求するケースもまだあります。
なので「新しいUTF-8を選んでおけば絶対安全」という話ではありません。
取込先が「Shift_JIS」「UTF-8 BOM付き」などと指定しているなら、その仕様が正解です。
.csv という拡張子だけでは文字コードは分かりません。
分からなくて普通です。
出力元・取込先の仕様が分からなければ、UTF-8とShift_JIS系でプレビューして、日本語が自然に読めるかを見る方が早いこともあります。
BOMという名前なのに、UTF-8では“Byte Order”を決めていません
UTF-8の先頭に EF BB BF という3バイトが付くことがあります。
これがBOMです。
名前は Byte Order Mark なんですが、ここが少し面白いところで、UTF-8にはUTF-16/32のようなバイト順問題がありません。
Unicode Consortiumも、UTF-8でBOMを使う場合は、バイト順を指定するためではなく、「これはUTF-8ですよ」と示す署名として使われると説明しています。
つまり「UTF-8」と「UTF-8 BOM付き」は、文字の表現方式そのものが別物というより、先頭に識別用の印があるかどうかです。
ただしBOMは、付ければ必ず互換性が上がる魔法の印ではありません。
BOMを期待しないシステムもあります。
なので、ここでも最終的には相手の仕様です。
「UTF-8 BOM付き」と指定されているなら付ける。「UTF-8」とだけ書かれているなら、そのシステムの例や仕様を優先します。
そして一番気付きにくいのが、「普通に開けたCSV」です
文字化けならすぐ分かります。
全部A列でも気付きます。
でもExcelで普通に表になっていると、人は安心します。
ここがむしろ危ないことがあります。
例えばCSVにはこう入っていたとします。
00123
商品コードなら5文字であることに意味があります。
でもExcelが「これは数値だろう」と判断すると、123 として扱うことがあります。
数字としては同じ。
商品コードとしては別物です。
さらに、長い番号が指数表記になったり、日付っぽい文字列が日付に変換されたりすることがあります。
CSV自身が「これは商品コードです」と型を持っていないので、読み込み側が意味を推測しているわけです。
CSVで怖いのは、開けないことより、普通に開けて意味だけ変わることがある点です。
Excelで大事なCSVを扱うなら、「開く」より「取り込む」と考えます
業務CSVなら、ダブルクリックしてそのまま編集するより、Excelを先に開いて [データ]→[テキストまたはCSVから] を使う方が安全です。
読み込み前にプレビューが出るので、
- 文字コード
- 区切り文字
- 列の分かれ方
- IDや日付らしい列
を一度見てから進められます。
Microsoftの現在のExcelには、先頭ゼロ、長い数値、Eを含む値、日付らしい文字列などの自動データ変換を制御する設定もあります。
ここで考え方として大事なのは、数字に見えるかではなく、計算する値かどうかです。
SKU、郵便番号、会員番号、注文IDなどは、数字だけでも「識別子」です。
識別子なら文字列として守る。
これだけでもかなり事故が減ります。
RFC 4180は“CSVの法律”ではありません。でも基準を持つにはかなり便利です
ここで急に RFC という言葉が出てきます。RFCは、インターネット技術の仕様や慣習を公開文書としてまとめたものです。
RFC 4180 は、その中でもCSVの一般的な書き方を整理した文書です。「Informational RFC」と呼ばれる種類で、法律や強制規格というより、広く使われている形式を共有するための参考文書と考えると分かりやすいです。
CSVには、歴史的にいろいろな実装があります。
なので、RFC 4180が「世の中のCSVは全部この形式でなければならない」と決めているわけではありません。
むしろRFC自身が、CSVにはさまざまな仕様や実装があることを前提にしています。
それでも、
- フィールドはカンマで区切る
- カンマ・改行・ダブルクォートを含む値は引用する
- 引用フィールド内の
"は""として表す text/csvというMIME typeを使う
といった「普通のCSV」を考えるときの基準になります。
取込先に独自仕様があるなら、その仕様を優先。
独自仕様が見当たらないときは、RFC 4180を共通言語として使う。
この距離感で見るのが実務ではちょうどいいです。
CSVを壊さず往復させるなら、最後に“保存後のCSV”を見ます
CSV作業で見落としやすいのが、編集画面と最終ファイルは別物だということです。
Excel上で正しく見えていても、最後に別システムへ渡すのは、Excelの画面ではなく保存されたCSVファイルです。
なので、重要なCSVなら次の順で進めます。
- 原本をコピーして残す。
- 文字コードと区切り文字を確認する。
- ID・コード・日付など、自動変換されたくない列を決める。
- Excelへ意図して読み込む。
- 編集する。
- 原本とは別名でCSVへ出力する。
- 出力したCSVをもう一度開く/検査する。
- 少量で取込テストする。
最後の7番が大事です。
「Excelで正しく見えた」ではなく、いま相手へ渡そうとしているCSVが正しいことを確認します。
行きと帰りで同じ意味を保てているかを見るので、こういう確認をround-tripとして考えると分かりやすいです。
迷ったら、症状からこの順で見れば大丈夫です
日本語が読めない
→ UTF-8 / Shift_JISなど文字コードを見る。
文字は読める。でも全部A列
→ カンマ / TAB / セミコロンなど区切り文字を見る。
途中の行だけ列がずれる
→ 値の中のカンマ・改行・ダブルクォートを見る。
普通に開ける。でも 00123 が 123 になる
→ Excelなど読み込み側の自動変換を見る。
保存したら別システムでエラーになる
→ 再出力したCSVの文字コード、ヘッダー、列数、値を原本・取込仕様と比較する。
全部の知識を覚える必要はありません。
構造・文字・解釈。まずどこで問題が起きているかを分ける。
そこまでできれば、CSVはかなり扱いやすくなります。