PHPでDBからデータを抜き出してCSVファイルを作成するということは度々あるのですが、そのときに問題になることが幾つかあります。
DBから抜き出した情報にダブルクォーテーション「"」やシングルクォーテーション「'」、カンマ「,」など、Excelで読み込んだときに具合の悪い文字が入っていることが
普段PHPでDBから情報を抜き出して表示するときにはエスケープ処理を行いますが、その方法としてはダブルクォーテーションなどの直前にバックスラッシュ「\」をつけます。
これはPHPなら「adslashes()」や「htmlspecialchars()」などを使えば簡単に行うことができますが、こうやってエスケープされた文字をExcelで開いてもエスケープしてくれません。
CSVの一般的な書式「RFC 4180」を読んでいくと次のような文章があります。
RFC 4180 Common Format and MIME Type for CSV Files October 2005
4. Within the header and each record, there may be one or more
fields, separated by commas. Each line should contain the same
number of fields throughout the file. Spaces are considered part
of a field and should not be ignored. The last field in the
record must not be followed by a comma. For example:
aaa,bbb,ccc
5. Each field may or may not be enclosed in double quotes (however
some programs, such as Microsoft Excel, do not use double quotes
at all). If fields are not enclosed with double quotes, then
double quotes may not appear inside the fields. For example:
"aaa","bbb","ccc" CRLF
zzz,yyy,xxx
6. Fields containing line breaks (CRLF), double quotes, and commas
should be enclosed in double-quotes. For example:
"aaa","b CRLF
bb","ccc" CRLF
zzz,yyy,xxx
7. If double-quotes are used to enclose fields, then a double-quote
appearing inside a field must be escaped by preceding it with
another double quote. For example:
"aaa","b""bb","ccc"
こいつを翻訳にかけると次のような意味なんですが
RFC 4180 CSVファイルの共通のフォーマットおよびMIMEタイプ 2005年10月
4. ヘッダーと各レコード内では、1つまたは複数の可能性があります
フィールドを、コンマで区切られます。それぞれの行は同じ含める必要があります
ファイル全体のフィールドの数です。スペース一部と見なされる
フィールドを無視してはならない。の最後のフィールド
レコードには、カンマで続いてはならない。例えば:
aaa,bbb,ccc
5. 各フィールドには二重引用符で囲まれていない場合があります(ただし、
Microsoft Excelなどのいくつかのプログラムでは、二重引用符を使用しない )。
もしフィールド二重引用符、その後に同梱されていません
二重引用符は、フィールド内に表示されない場合があります。例えば:
"aaa","bbb","ccc" CRLF
zzz,yyy,xxx
6. フィールドを含む、改行(CRLF)は、二重引用符、カンマ
二重引用符で囲む必要があります。例えば:
"aaa","b CRLF
bb","ccc" CRLF
zzz,yyy,xxx
7. 場合、二重引用符で囲むフィールドにし、二重引用符に使用されます
フィールド内に表示されるとその前でエスケープする必要があります
別の二重引用符。例えば:
"aaa","b""bb","ccc"
簡単に説明すると
4. 改行コードは(CR+LF)を使用すること。
5. 改行コード(CR+LF)、ダブルクォーテーション、カンマを含むフィールドは ダブルクォーテーションで囲むのが望ましい。
6. フィールド内にダブルクォーテーションを含む場合、直前にダブルクォーテーションを付けてエスケープしなければならない。
7. ファイル内最終レコードの末尾には改行コードがあってもなくてもよい
ExcelでCSVを読ませるためには RFC4180 に準拠して、ダブルクォーテーションの前にダブルクオーテーションでエスケープする必要があると