文字化けしないように Web サービスを構築する
では、インポート・エクスポートしたCSVファイルが文字化けしないようにWebサービスを構築するにはどうしたら良いでしょうか? Webシステムで使っている文字コードはUTF-8の想定です。文字化けしないようにCSVファイルをダウンロードさせる
CSVをダウンロードさせる場合は簡単ですね。ファイルの先頭にBOMを追加すれば良いのです。例えば以下のようになります。
#!/usr/bin/perl -- use strict; use warnings; use utf8; use CGI; my $query = new CGI; #csv 用ヘッダを出力 binmode STDOUT, ':utf8'; $| = 1; #autoflush; print $query->header( -X_Content_Type_Options=>'nosniff', -Content_Type=>'application/force-download', -Content_Disposition=>qq{attachment;filename="utf8.csv"}, ); #BOM出力 print "\x{FEFF}"; #BOM のUnicode表記 #内容出力 print "1,株式会社山田商事,高橋,太郎,090-0987-6543,06-9999-8888\r\n"; print "2,三晃珈琲有限会社,吉田,隆,045-2345-6789,080-2222-1111\r\n";
文字化けしないようにCSVファイルを受け取る
一方アップロードされたCSVファイルを受け取る場合は、主に以下の3つの可能性があります。
- 先頭にBOMが付いたUTF-8
- 先頭のBOMの無いUTF-8
- Shift_JIS
どの文字コードが来るか分かりませんので、文字コードを自動判別して読み込み、BOMが付いていればこれを取り除きます。例えば以下のようになります。
use strict; use warnings; use utf8; require './open_binary.pl'; #文字コード自動判別用ライブラリ:別の記事参照 binmode STDOUT, ':utf8'; my $file = 'temp_uploaded.csv'; #アップロードファイルを受け取って保存しておく #文字コード判別してファイルハンドルを取得 my ($fh, $error) = &open_binary4read($file); #内容を読み取り if ($fh and !$error){ my $count = 0; while(<$fh>){ #先頭にBOM があれば除く $count == 0 and s/^\x{FEFF}//; #実際にはここでCSVのデータを取り込み処理 print $_; } close ($fh); } #一時保存したファイルを片付け。(必要なら保存する。) unlink $file;