AIで作ったCSVがExcelで文字化けする原因と直し方|BOMを1行で付ける

AIで作ったCSVの文字化けを直す記事のアイキャッチ。崩れた表が整った表になるイラスト

ZEN AI LAB のキャラクター ZEN

監修:ZEN AI LAB(ZEN)

人間1人とAI社員で動く会社です。記事の数値は自社の作業ログの実測、仕様や料金は公式の一次情報で確認しています。確認した日付は本文に書いています。

AIに売上表や一覧をCSVで作らせ、Excelで開くと日本語が読めない文字になることがあります。Microsoftは、BOMという目印付きで保存したUTF-8(=いま標準の文字の保存形式)のCSVなら通常どおり開けると案内しています。目印が無いファイルは、1行のコマンドで付けるか、Excelの[データ]から取り込めば開けます。

この記事で分かることは次のとおりです。

  • 文字化けしたCSVの調べ方
  • 手元のファイルにBOMを付ける方法
  • AIへの具体的な頼み方
  • 異なるCSVを壊さずに結合する方法

ZEN AI LABでは2026-09-19にCodexとClaude CodeでCSVを作り、ファイルの先頭を調べました。BOMの追加とCSV結合も実ファイルで検証しています。読み終えたら、手元のsales.csvを調べて修正できます。

化けたらまず先頭3バイトを見る

CSVが文字化けしていても、中の文字まで失われたとは限りません。文字コード(=文字を保存するときの決まり)と、開く側の読み方が合っているかを切り分けます。BOMは、ファイルの先頭に付く、UTF-8で書かれていることを示す目印です。

文字化けしたCSVを直す流れ。先頭3バイトの値で、そのまま開く・BOMを付ける・データタブから取り込むに分かれる図

ZEN AI LABのテストでAIが作った14ファイルは、すべてUTF-8として正しく読めました。化けて見えても、中身の文字は残っていました。後述のBOMを付けるPythonの1行がエラーなく終われば、そのファイルはUTF-8として読めています。先頭3バイトを見るコマンドでは、UTF-8かどうかまでは分かりません。

確認は次の順番で進めます。

  1. 化けた画面のまま上書き保存せずに閉じます。
  2. 元のファイルをコピーしておきます。
  3. CSVのあるフォルダでコマンドを実行し、先頭3バイト(=ファイルのいちばん最初の3つの値)を見ます。
  4. EF BB BFならBOMあり、E5 95 86のように別の値ならBOMなしです。

Pythonで先頭を見る

sales.csvは自分のファイル名に置き換えます。このコマンドはPythonが入っているPCで動きます。Pythonが無い場合は、後述するPowerShellのFormat-Hexで見られます。

python -c "print(open('sales.csv','rb').read(3).hex(' ').upper())"

BOMありの実出力はEF BB BFでした。BOMなしで最初の文字が「商」の実出力はE5 95 86でした。16進数は、ファイル内のバイトを短い記号で表したものです。

PowerShellでは次を実行します。

Format-Hex -Path sales.csv

00000000で始まる行の、最初の3つの値を見ます。EF BB BFならBOMがあります。

Microsoftのサポートページは、BOM付きのUTF-8のCSVなら通常どおり開けると案内しています(2026-09-19確認)。

化けた文字の例(Pythonで再現)

次はPythonによるシミュレーションです。Excelの画面を再現したものではありません。BOMなしのUTF-8をcp932(Windowsで使われるShift_JIS)として読み、読めない部分を�に置き換えました。

元の見出しcp932として読んだ表示
商品名,売上金額,販売日蝠�蜩∝錐,螢イ荳企≡鬘�,雋ゥ螢イ譌・
日付,商品名,数量,単価,売上金額譌・莉�,蝠�蜩∝錐,謨ー驥�,蜊倅セ。,螢イ荳企≡鬘�

BOMを1行のコマンドで付ければ開ける

先頭がEF BB BFではなく、UTF-8として読めるファイルにはBOMを付けられます。上書きするため、次の順番を守ってください。

  1. 元のファイルをコピーします。
  2. CSVのあるフォルダで次のコマンドを実行します。
python -c "p='sales.csv';s=open(p,encoding='utf-8-sig',newline='').read();open(p,'w',encoding='utf-8-sig',newline='').write(s)"
  1. もう一度、先頭3バイトを見るコマンドを実行し、EF BB BFを確かめます。
  2. Excelでファイルを開きます。

ZEN AI LABでは、BOMなしのUTF-8ファイルに実行しました。ファイルは134バイトから137バイトになり、先頭がEF BB BFに変わりました。同じコマンドをもう1回実行してもBOMは1つのままで、改行(LF)と本文は元と同じでした。

utf-8-sigは、BOMを扱うためのPythonの指定です。Pythonの公式ドキュメントによると、書き込み時にはUTF-8のBOMを先頭に付け、読み込み時には先頭のBOMがあれば飛ばします(2026-09-19確認)。

対象がShift_JISだったテストでは、次のエラーで止まりました。

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8f in position 0: invalid start byte

終了コード1で停止し、ファイルは変わりませんでした。0x8fはファイルの中身によって変わります。エラーが出た場合は上書きを続けず、後半の判定付き結合を使ってください。

Pythonが無いときはPowerShellで付ける

先に元のファイルをコピーしてください。そのうえで、CSVのあるフォルダでPowerShell 5.1の次の1行を実行します。

$t = Get-Content -Path .\sales.csv -Raw -Encoding UTF8; Set-Content -Path .\sales.csv -Value $t -Encoding UTF8 -NoNewline

BOMなしUTF-8の134バイトのファイルは137バイトになり、先頭はEF BB BFでした。2回実行してもBOMは重ならず、中身と改行(LF)は変わりませんでした。

ただし、Shift_JISのファイルに使うと、エラーが出ないまま日本語が置換文字(�)40個に置き換わりました。PowerShellの1行は、UTF-8かどうかの確認には使えません。Shift_JISかもしれないファイルは、[データ]タブから取り込んでください。PowerShellの1行を実行した後に日本語が�になっていたら、コピーしておいた元のファイルに戻して、[データ]タブから取り込みます。

ファイルを書き換えたくない場合も、Microsoftの案内にある[データ]タブからの取り込み(日本語版の表記は[テキスト/CSV からデータを取得])を使えます(Microsoftサポート、2026-09-19確認)。

AIには「Excelで開く」と伝える

次からCSVを作らせるときは、用途までプロンプトに含めます。今回使った文は次の2つです。

CodexとClaude Codeに作らせたCSVのBOMの有無。Excelで開くと伝えた7回はすべてBOM付き

「売上の日本語CSVを3行作って sales.csv に保存して」

「売上の日本語CSVを3行作って sales.csv に保存して。Excelで開くので文字化けしないように」

ZEN AI LABは2026-09-19に、Windows 11 ProのPCでCodex CLIとClaude Code CLIを動かしました。空のフォルダを作業場所にし、標準の設定で3回ずつ実行しました。ユーザー設定を読まない条件でも1回ずつ試し、合わせて16回実行しました。Codexをcodex execで動かす方法は別の記事にまとめています。

ツールプロンプトBOM ありBOM なし
CodexExcel と言わない21
CodexExcelで開くので文字化けしないように30
Claude CodeExcel と言わない22
Claude CodeExcelで開くので文字化けしないように40

Codexは標準条件の3回です。Claude Codeは標準条件3回と、ユーザー設定を読まない条件1回です。Codexのユーザー設定を読まない条件の2回は保存できなかったため、表に含めていません。

Excelと言わない文で作られた7ファイルは、BOMありが4つ、BOMなしが3つでした。標準条件ではCodexもClaude Codeも3回中2回がBOMあり、1回がBOMなしでした。Claude Codeのユーザー設定を読まない条件の1回もBOMなしでした。

「Excelで開くので文字化けしないように」と伝えた7ファイルは、すべて先頭3バイトがEF BB BFでした。内訳はCodexが3つ、Claude Codeが4つです。回数が少ないため、別の実行でも同じ結果になるとは限りません。

このテストでは、Claude Codeにファイルの書き込みだけを許可していました。BOMなしの2回は、BOMが無いことと、BOMを付けるコマンドには許可が必要だったことを返答で伝えました。結果には、許可の条件も関係しています。

ほかの依頼文はプロンプト集で確認できます。

AIの「BOM付きです」は先頭を見て確かめる

AIの返答に文字コードの説明があっても、ファイルの実体は先頭3バイトで確かめます。確認には、前に示したPythonコマンドを使います。

AIの最後の返答は、14ファイル中13で文字コードとBOMの有無に触れ、実際のバイトと一致していました。残る1回は、CodexがBOMなしのファイルを作り、文字コードに触れず「保存しました」と返しています。

Claude Codeが「先頭3バイトがBOMであることを確認済み」という趣旨を返した回もありました。そのファイルは実際にBOMありでしたが、どう調べたかは記録に残っていません。

BOM付きのCSV同士はそのまま連結しない

BOMはファイルの先頭に置く目印です。BOM付きのCSVをコピー機能で単純につなぐと、後ろのファイルのBOMが途中に残ります。

ZEN AI LABでは、BOMありのCSVを2つ、copy /b a.csv+b.csv merged.csvで連結しました。BOMは0バイト目と137バイト目の2か所に残りました。utf-8-sigで読んでも、2つ目の見出し行の先頭には見えない文字(U+FEFF)が残りました。

BOM付きのCSVをPythonのcsv.DictReaderでencoding='utf-8'として読むと、row['商品名']がKeyError: '商品名'になりました。列名は'\ufeff商品名'で、先頭に見えない1文字が付いていました。encoding='utf-8-sig'にすると読めました。

複数のCSVはバイトのまま連結せず、ファイルごとに読み込んで見出しとデータを分けます。

Shift_JISが混ざるときはファイルごとに判定する

ZEN AI LABは2026-09-15に、Windows 11 Pro(10.0.26200)とPython 3.13.1で再現テストをしました。同じ3行のデータを、UTF-8(BOMあり)・UTF-8(BOMなし)・Shift_JIS(cp932)の3ファイルに保存しました。

データには①・㈱・髙・~・〜・𠮷を入れました。読み方や書き方を変え、5つの壊れ方を再現しました。

症状何が起きたか見分け方
読めない文字になるUTF-8をShift_JISとして読むと、取引先,金額,備考が蜿門シ募..,驥鷹。.,蛯呵.のようになった。BOMありでは先頭にᄏソも付いたエラーが出ず処理が終わるため、見出しや本文を見る
読み込みが止まるShift_JISをUTF-8として読むとUnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 0: invalid start byteで止まったUnicodeDecodeErrorと指定した文字コードを見る
一部の文字を書けない𠮷をcp932で書こうとするとUnicodeEncodeErrorになった。errors='replace'では185バイトから129バイトに減り、その文字が消えた書き出し時のエラーと変換前後の内容を見る
見出しが一致しないBOMを考えずに読むと見出しが['\ufeff取引先', '金額', '備考']となり、h[0] == '取引先'はFalseだった先頭3バイトと見出しの実体を見る
コンソールで止まるWindowsのcp932のコンソールへUTF-8の文字をprintするとUnicodeEncodeErrorで止まったPYTHONIOENCODING=utf-8を付けると再現時は出なくなった

結合は次の順番で進めます。

  1. 結合するCSVをinフォルダに集めます。
  2. 次のコードをmerge_csv.pyとして、inフォルダがある場所に保存します。
  3. その場所で python merge_csv.py を実行します。
import csv, glob, io

def read_rows(path):
    raw = open(path, "rb").read()
    for enc in ("utf-8-sig", "cp932"):  # utf-8-sig は BOM があってもなくても読める
        try:
            text = raw.decode(enc)
            return enc, list(csv.reader(io.StringIO(text, newline="")))
        except UnicodeDecodeError:
            continue
    raise ValueError(f"文字コードを判定できない: {path}")

header, out_rows = None, []
for path in sorted(glob.glob("in/*.csv")):
    enc, rows = read_rows(path)
    print(path, enc, rows[0])
    if header is None:
        header = rows[0]
    elif rows[0] != header:
        print("  見出しが違うので結合しない:", path)
        continue
    out_rows += rows[1:]

with open("merged.csv", "w", encoding="utf-8-sig", newline="") as f:
    w = csv.writer(f, lineterminator="\r\n")
    w.writerow(header)
    w.writerows(out_rows)
print("merged.csv:", len(out_rows), "行")
  1. 出力されたmerged.csvに先頭3バイトを見るコマンドを実行し、EF BB BFを確かめます。

コードは各ファイルをutf-8-sig、cp932の順で読みます。最初のファイルの見出しを基準にし、見出しが違うファイルは結合せずに知らせます。最後にBOM付きのUTF-8でmerged.csvを書き出します。

2026-09-19のテストでは、AIが作った3ファイルを使いました。同じ内容をShift_JISにした1ファイルと、見出しが違う1ファイルも加え、計5ファイルで動かしました。

5ファイルとも文字コードを判定できました。Shift_JISの1つはcp932、残りはutf-8-sigでした。見出しが違う1ファイルは結合せず、残る4ファイルのデータを12行に結合しました。書き出したmerged.csvは先頭にBOMが1つあり、改行はCRLFでした。

2026-09-15の再現では、先頭3バイトがEF BB BFならutf-8-sigと判定しました。違う場合はUTF-8、cp932の順に試しました。3ファイルの文字コードをすべて正しく判定し、9行に結合できました。出力したファイルの先頭3バイトはEF BB BFでした。

このコードが試す文字コードはutf-8-sigとcp932だけです。UTF-16などは判定できず、空のファイルも想定していません。見出しの並びが1文字でも違うファイルは結合しません。

この記事で確かめていないこと

Microsoftの案内には、BOMなしのUTF-8をダブルクリックした場合の読み方や表示の記載がありません。ZEN AI LABの作業用PCにはExcelが入っていないため、実際の画面表示も調べていません。記事内の文字化け例はPythonによるシミュレーションです。

MicrosoftはPower Queryとテキストのインポート機能を案内しています。日本語版には[テキスト/CSV からデータを取得]という表記もありますが、実際のメニュー表示は見ていません。Excelの版によって名前が異なる可能性があります。

ChatGPTのWeb画面でCSVを作成して取得する操作は対象外です。そこで得たCSVにも、先頭3バイトを調べ、UTF-8ならBOMを付ける手順は使えます。

「UTF-8のBOM付きで保存して」という別の文言はテストしていません。Excelで保存形式を選んだ後の文字コードや、LFのCSVを開いた際の表示も調べていません。

今回の結果は2026-09-19時点のCodex CLIとClaude Code CLIによるものです。Codexの標準条件はgpt-5.6-sol、reasoning lowでした。モデル、設定、実行日が変われば結果も変わる可能性があります。

月ごとに分かれたCSVを1つにまとめる作業を毎月くり返すなら、ZEN AI LABが作ったWindows用のツールCSVMergeFlow(noteで販売・自社商品)も使えます。

価格・動作環境・無料版の有無は、CSVMergeFlow の商品ページにまとめています。

まとめ

  • 文字化けしたCSVは、先頭3バイトがEF BB BFかを最初に調べます。
  • BOMなしのUTF-8なら、元のファイルをコピーしてからBOMを付けます。
  • 複数のCSVは単純に連結せず、ファイルごとに文字コードと見出しを調べます。
  1. 今日、元のファイルをコピーしてから、先頭3バイトを見るコマンドを実行します。
  2. EF BB BFが無く、UTF-8として読める場合はBOMを付けます。
  3. 次にAIへ頼むときは「Excelで開くので文字化けしないように」と用途まで伝え、受け取ったファイルも調べます。

業務で使う手順を続けて探す場合は、業務の自動化の記事一覧をご覧ください。