はじめに
Windows環境のExcelで UTF-8 のCSVファイルを開いて編集・保存すると、勝手に ANSI(Shift-JIS)などの文字コードに変換されてしまい、システム側に再アップロードした際に文字化けが発生する……という経験はありませんか?
「テキストエディタで開き直して保存し直す」
「毎回コマンドラインで変換する」
といった作業が非常に面倒に感じたため、「ファイルをアップロードするだけで、即座に安全に文字コードを相互変換できる軽量ツール」を開発しました。
本記事では、開発したツールの概要と、現場での不具合を根絶するために工夫したPHPでの実装ポイントについて紹介します。
作ったツール
CSV文字コード変換ツール
👉 https://ss-infra.net/csv/
主な機能
- 文字コードの相互変換: UTF-8 (BOMあり/なし)、Shift_JIS (ANSI / CP932) に対応
- ドラッグ&ドロップ対応: ファイルを選んで一発で変換・ダウンロード
- シンプル&高速動作: 複雑な設定なしで誰でもすぐ使えるWebツール
開発の背景と抱えていた課題
WindowsのExcelは、標準でCSVを読み書きする際の文字コード挙動が特殊です。
特にUTF-8で作成したCSVをExcelで開いて作業し、保存を行うと自動的にANSI(Shift-JIS)にフォールバックされてしまうことが多々あります。
この問題に対して手軽に使えるツールを検討したものの、設定項目が多く操作が複雑だったり、ファイルを外部サーバーにアップロードさせる仕様のものが多く、業務データや個人情報を扱うにはセキュリティ面で不安がありました。
そこで、「シンプルで迷わないUIと、自分自身がストレスなく快適に使える変換環境」を目指して開発をスタートしました。
技術的なポイント:現場の「地味なトラブル」を潰すPHP実装
PHP側でアップロードされたファイルを受け取り、単なる文字コード変換だけでなく、Excelで開いた際のフォーマット崩れや文字化けを防ぐための補正処理を行っています。
1. 機種依存文字を防ぐ文字コード補正
Windows特有の環境依存文字(波ダッシュ〜や丸数字①など)の文字化けを防ぐため、検出結果がSJIS系だった場合は明示的に SJIS-win に補正して変換を行います。
// 1. 文字コード判別とUTF-8変換
$detected_encoding = mb_detect_encoding($content,
['SJIS-win', 'CP932', 'UTF-8', 'EUC-JP', 'ASCII'],
true
);
if (!$detected_encoding) {$detected_encoding = 'SJIS-win';
}
$from_encoding = (in_array($detected_encoding, ['SJIS-win', 'CP932'], true)) ? 'SJIS-win' :$detected_encoding;
$converted_content = mb_convert_encoding($content, 'UTF-8',$from_encoding);
2. 改行コードと区切り文字の自動補正
文字コードだけでなく、MacとWindowsで混在しがちな改行コードの統一(CRLF化)や、TSV(タブ区切り)・全角カンマによる読み込みエラーを防止する前処理を挟んでいます。
// 2. 改行コードを Windows/Excel標準の CRLF (\r\n) に統一
$converted_content = str_replace(["\r\n", "\r"], "\n", $converted_content);
$converted_content = str_replace("\n", "\r\n", $converted_content);
// 3. 区切り文字の補正(タブ区切り(TSV)や全角カンマを半角カンマに展開)
if (strpos($converted_content, "\t") !== false && strpos($converted_content, ",") === false) {
$converted_content = str_replace("\t", ",", $converted_content);
}
$converted_content = str_replace(',', ',',$converted_content);
3. セッション保持による安全なダウンロード設計
ユーザーの業務データや個人情報を守るため、アップロードされたファイルや変換データをサーバー上に永続保存(ストレージ保持)せず、セッション経由で提供した後に即時消去(unset)する設計にしています。
// BOMおよび出力設定
$bom_option =$_POST['bom_option'] ?? 'with_bom';
$bom = ($bom_option === 'with_bom') ? "\xEF\xBB\xBF" : '';
$output_filename = 'utf8_' . pathinfo($file['name'], PATHINFO_FILENAME) . '.csv';
// セッションに一時保持
$_SESSION['converted_data'] = [
'filename' => $output_filename,
'content' => $converted_content,
'bom' => $bom
];
ここがポイント:
BOMのあり・なしをユーザーが選択できる仕様にしつつ、ダウンロード完了時には unset($_SESSION['converted_data']) を実行してサーバー上から即座にデータを削除しています。セキュリティ面でも安心して使えるような設計を心がけました。
おわりに
社内業務や開発現場で「ExcelのCSV文字化け・文字コード変換」に悩まされている方は、ぜひ一度試してみてください!
ご意見・改善のご要望などがあれば、ぜひQiitaのコメント欄やフィードバックでお知らせいただけると嬉しいです!