問題に直面した状況
Google スプレッドシートや Mac の Numbers では問題なく開けるのに、Windows の Excel でだけ日本語が “����” に文字化けしてしまう現象に遭遇。
解決方法
原因は、Excel が CSV や TSV ファイルを Shift-JIS(CP932)前提で読み込む仕様にありました。
対策として、ファイルの先頭に UTF-8 の BOM(バイトオーダーマーク)を追加することで、Excel に「 UTF-8 ですよ」と正しく認識させることができ、文字化けを防ぐことができました。
はじめに
Windows版の Excel は、CSV や TSV ファイルを開く際に Shift-JIS(CP932)でエンコードされているものとして読み込む仕様になっています。
そのため、UTF-8 でエクスポートされたファイルをそのまま開くと、日本語が “����” といった文字化けを起こすケースがあります。
この問題を防ぐには、ファイルの先頭に UTF-8 の BOM(Byte Order Mark)を付与することが有効です。
Excel は BOM の存在によってそのファイルを UTF-8 として正しく認識し、文字化けを防いでくれます。
なお、Google スプレッドシートや Mac の Numbers では UTF-8 の BOM がなくても問題なく表示されるため、Excel 向けに限定して BOM を付けておくのがもっとも安全で汎用的な方法です。
CSV:UTF-8+BOM ダウンロード用コード
UTF-8+BOM に対応した CSVエクスポート処理をフロントエンドで完結させる関数です。
Excel での文字化けや数式インジェクションを考慮しており、簡単に導入できて、日常業務のデータ抽出にも応用可能です。
/**
* exportTableToCSV_BOM.js
* テーブル -> CSV(UTF-8+BOM)をブラウザで即ダウンロード
*/
export function exportTableToCSV_BOM(tableSelector, skipSelector = '#year-select') {
// 1. テーブル行を取得
const rows = document.querySelectorAll(`${tableSelector} tr`);
const csvLines = [];
rows.forEach(row => {
// 2. スキップ行
if (row.querySelector(skipSelector)) return;
// 3. 各セルを加工
const cells = Array.from(row.querySelectorAll('td,th'), col => {
let text = col.innerText.replace(/"/g, '""').trim();
// 4. 数式インジェクション対策
if (/^[=+\-@]/.test(text)) text = '\u200B' + text;
return `"${text}"`;
});
// 5. カンマ区切りで結合
csvLines.push(cells.join(','));
});
// 6. BOM + 改行で一気に文字列化
const bom = '\uFEFF';
const blob = new Blob([bom + csvLines.join('\n')], {
type: 'text/csv;charset=utf-8;'
});
// 7. ダウンロードリンク作成&発火
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = makeFilename('export');
link.click();
// 8. 後片付け
setTimeout(() => URL.revokeObjectURL(link.href), 10_000);
}
/**
* ファイル名生成ヘルパー
*/
function makeFilename(prefix) {
const year = new Date().getFullYear();
return `${prefix}_${year}.csv`;
}
なぜ Excel だけ文字化けするのか?
UTF-8 で保存した CSV や TSV ファイルを Excel で開いたとき、“����” のように日本語が文字化けする現象に悩まされたことはありませんか?
その主な理由は、Excel のエンコーディング処理にあります。
-
Excel は Shift-JIS 前提で読み込む
日本語環境の Excel は、CSV/TSV を開く際に 既定で Shift-JIS(CP932)として解釈します。
そのため、UTF-8 で保存されたファイルをダブルクリックで開くと、文字化けが発生します。参考:Super User – How to set character encoding when opening a CSV file in Excel?
-
BOM(Byte Order Mark)付きなら認識してくれる
ファイルの先頭にEF BB BF
という3バイトの BOM(UTF-8の目印) を付けておくと、Excel はそのファイルを UTF-8 として正しく読み取ってくれます。 -
BOM がないとどうなるか?
UTF-8 の 2バイト文字が バラバラに読み込まれ、意味不明な文字列(“����”など) として表示されてしまいます。
実際に確認した動作結果
環境 | 拡張子 | BOMあり | BOMなし |
---|---|---|---|
Windows / Excel 2021 | .csv / .tsv |
✅ 正常に表示 | ❌ 文字化け(����) |
macOS Numbers | .csv / .tsv |
✅ 正常に表示 | ✅ 正常に表示 |
Google Sheets | .csv / .tsv |
✅ 正常に表示 | ✅ 正常に表示 |
🔍 Excel は「ダブルクリックで開く」場合に Shift-JIS 前提で動作します。
Power Query などからインポートする場合は、文字コードの指定が可能なため、BOM なし UTF-8 でも読み込めます。
よくある Q&A
Q. なぜ TSV(タブ区切り)を使うの?
CSV(カンマ区切り)でももちろん構いませんが、セル内にカンマを含むデータ(例:「明太子,(辛口)」など)を扱う場合、カンマが列区切りと誤解されて 列ズレが発生する可能性があります。
TSV(タブ区切り)はその点で安全性が高く、Excel も自動的にタブを区切り文字として認識するため、実務上のトラブルを避けたい場合はTSVが有効です。
💡参考:TSV vs CSV - Pros and Cons
Q. UTF-8 + BOM は他のツールに悪影響ないの?
BOM(Byte Order Mark) は Excel の文字化け回避には便利ですが、Unix 系のコマンドラインツール(cut
, awk
, grep
など)では 行頭の余分な3バイトとしてそのまま処理され、意図しない出力になることがあります。
このような場合は、以下のような方法で BOM を除去できます:
-
sed
を使う:
sed '1s/^\xEF\xBB\xBF//' file.csv
- iconv で BOM を除去しながら UTF-8 に変換:
iconv -c -f UTF-8 -t UTF-8 file.csv
Q. CSVインジェクションは防げている?
はい、防いでいます。
CSVファイルでセルの先頭が =, +, -, @ のいずれかだと、Excel はそれを関数や数式と誤解し、自動実行してしまうことがあります(CSVインジェクション)。
これを防ぐため、今回のコードでは 先頭にゼロ幅スペース(\u200B)を挿入しています。
これにより、Excel では数式ではなく「ただの文字列」として安全に表示されます。
まとめ
- Excel だけ文字化けしてしまう原因は、デフォルトで Shift-JIS としてファイルを読み込む仕様にあります。
- UTF-8 + BOM を付与して保存すれば、Excel でも文字化けせずに正しく表示されるようになります。
- あわせて、ゼロ幅スペース(
\u200B
)を使ったCSVインジェクション対策も入れておけば、安心してデータを扱えます。
採用拡大中!
アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニアを募集しています!
少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう!
お問い合わせはこちらから↓
https://official.assisteng.co.jp/contact/