0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Excelだけ「“����” 」になるCSV/TSV文字化け対策 ── UTF-8+BOMで即解決!【備忘録】

Posted at

問題に直面した状況

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 を付けておくのがもっとも安全で汎用的な方法です。

参考: Microsoft公式のサポート記事

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 のエンコーディング処理にあります。

  1. 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?

  2. BOM(Byte Order Mark)付きなら認識してくれる
    ファイルの先頭に EF BB BF という3バイトの BOM(UTF-8の目印) を付けておくと、Excel はそのファイルを UTF-8 として正しく読み取ってくれます。

    参考:Microsoft Power Query CSV Docs

  3. 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/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?