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


 ## 問題に直面した状況  
 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公式のサポート記事](https://support.microsoft.com/en-us/office/opening-csv-utf-8-files-correctly-in-excel-8a935af5-3416-4edd-ba7e-3dfd2bc4a032)



## CSV：UTF-8+BOM ダウンロード用コード

UTF-8+BOM に対応した **CSVエクスポート処理をフロントエンドで完結させる関数**です。
Excel での文字化けや数式インジェクションを考慮しており、簡単に導入できて、日常業務のデータ抽出にも応用可能です。

```js
/**
 * 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?](https://superuser.com/questions/280603/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](https://learn.microsoft.com/en-us/power-query/connectors/text-csv)

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](https://stackoverflow.com/questions/17879198/why-are-tab-separated-files-considered-better-than-csv)



### Q. UTF-8 + BOM は他のツールに悪影響ないの？

**BOM（Byte Order Mark）** は Excel の文字化け回避には便利ですが、Unix 系のコマンドラインツール（`cut`, `awk`, `grep` など）では **行頭の余分な3バイト**としてそのまま処理され、意図しない出力になることがあります。

このような場合は、以下のような方法で BOM を除去できます：

- `sed` を使う：  
```sh
  sed '1s/^\xEF\xBB\xBF//' file.csv
   ```
- iconv で BOM を除去しながら UTF-8 に変換：

 ```sh
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/](https://official.assisteng.co.jp/contact/)