こんばんは、Webプログラマの篠田です。
4月に入り、暖かくなってきましたね。1年のなかでも活動しやすい季節になりましたが睡魔との戦いが最も激しい季節でもありますね。
みなさんも睡魔に負けないようお過ごしください。
さて、前回(私の回の)ご紹介した「BOMの地雷を踏み抜かない正しい文字コードとの接し方」でご紹介した「BOM付きUTF-8」が無双するコードを、ご紹介したいとおもいます。
この記事の目次
「BOM付きUTF-8」の無双(?)のコード
では早速、下記のコードで「BOM付きUTF-8」のCSVファイルを作ることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php $view = ""; $list = array( array( '三石琴乃', '田中敦子', '榊原良子', '池田昌子', ), array( '髙橋孝治', '関俊彦', '田の中勇', ), ); foreach ($list as $value) { //配列の内容を「,」区切りで連結する $view .= implode(",", $value). "\r\n"; } $view = pack('C*',0xEF,0xBB,0xBF). $view; //「$view」を「koe.csv」ファイルに書き出しする file_put_contents("koe.csv", $view); |
では、ポイントだけ見ていきましょう。
コード解説(1)
ポイントは、「UTF-8」の「BOM」であるコード「0xEF」「0xBB」「0xBF」をカンマ区切りにされた文字列の先頭に連結します。
「0xEF」「0xBB」「0xBF」は特殊なバイナリ文字列として扱わないといけないため通常の文字連結では「BOM」として認識してくれません。
そのため、PHP関数の「pack関数」でバイナリ文字列に変換して連結させます。
「pack関数」の第1引数にある「C*」は「符号なしchar型の繰り返し」という意味になります。
これで書きだされたCSVファイルを「Windows版 Microsoft Excel」で開いてみてください。
綺麗に表示されたのではないですか?
※特殊文字の「髙(ハシゴたか)」も綺麗に表示されていますね。
めでたし、めでたし。
さすが「Microsoft Excel」と思いました!
はい、めでたくなかった方がいるのではないでしょうか。
そう、「Mac版Microsoft Excel」で開いた方は残念な結果になったと思います。
これは完全に盲点だったのですが、どうやらMac版とWindows版では同じMicrosoft Excelでも文字コードの捉え方が違うようです。
さすが「Microsoft Excel」一筋縄ではいかないですねww
解決方法のコードをご紹介しましょう。
「Mac版Microsoft Excel」で表示させる
結論からいうと「BOM付きUTF-8」では無理です!!!
「Mac版Microsoft Excel」で表示させるためには「BOM付きUTF-16LE」という文字コードでかつ「TSV形式」でないとMac、Windows両方で表示可能なファイルを作ることができません。
というわけで下記のコードをご紹介しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php $view = ""; $list = array( array( '三石琴乃', '田中敦子', '榊原良子', '池田昌子', ), array( '髙橋孝治', '関俊彦', '田の中勇', ), ); foreach ($list as $value) { //配列の内容を「,」区切りで連結する $view .= implode("\t", $value). "\r\n"; } $view = pack('C*',0xFE,0xFF). mb_convert_encoding($view, 'UTF-16LE', 'UTF-8'); //「$view」を「koe.csv」ファイルに書き出しする file_put_contents("koe.csv", $view); |
コード解説(2)
ポイントは2箇所です。
作成したファイルがUTF-8であることが前提ですが、PHP関数「
mb_convert_encoding」を使って「UTF-16LE」という文字コードに変換します。
もうこの段階で負けていますが。。。気にせず次に行きましょう。
あとは「BOM」を付けてあげるだけなのですがUTF-8と同じBOMでは効果がありません。
文字コードごとに「BOM」が変わります。
今回は「UTF-16」の「LE(リトルエンディアン)」なのでBOMは「0xFF」「0xFE」になります。
※「LE(リトルエンディアン)」ついては長くなるので割愛
ちなみに「UTF-16のLE」と「UTF-16LE」というのがあるのですがこれは分類上別物になり、「UTF-16LE」の方は「BOM」が付けることができません。
ただ、ややこしいのがPHP関数「mb_convert_encoding」で「UTF-16のLE」というのが「UTF-16LE」に該当します。
※PHP関数「mb_convert_encoding」が取り扱える文字コードはこちら
なので、PHP関数「mb_convert_encoding」で変換した「UTF-16LE」の文字列に「BOM」をつけることができます。
あとは、CSVである「,」をタブを表す「\t」にして配列を連結させます。
出力ファイルの拡張子は「.csv」のままでOKです
※厳密には「.tsv」ですが、それではExcelが反応してくれないので「.csv」で偽装します。
さぁ、これでMacでも綺麗に表示されるはずです!!
まとめ
あまり大きな声では言えませんが、、、「仕様をまとめることはできなかったのか!?」と声を大にして言いたいというきもちですが、胸に閉まっておきたいと思います。
検証は、Mac・Windows両方で見ましょう!
※ちなみにOpenOfficeとかで動かないとかで動かない!というクレームはお断りですw