完全解决 CSV 字符编码问题!字符代码、BOM 和换行符的基础知识
大多数开发者都曾经历过打开CSV文件却发现字符显示混乱的情况。特别是对于包含日文的CSV文件,由于字符编码的差异,问题经常会发生。本文整合了相关知识,以便从根本上理解字符混乱的原因,并提供可靠的解决方案。
字符编码基础:<code>UTF-8</code> vs <code>Shift_JIS</code>
日本语 CSV 文件中出现问题的字符编码主要有以下两种:
UTF-8
当前的网络标准,是一种基于Unicode的字符编码,能够处理全球范围内的文字。在Linux、macOS和现代网络应用中,UTF-8是默认编码。它采用每个字符1到4字节的可变长编码,ASCII字符保持为单个字节。
Shift_JIS(CP932)
这是在 Windows 旧版应用程序和 Excel 较早版本中使用的日语字符编码。确切地说,Windows 环境中使用 CP932(Microsoft 对 Shift_JIS 的扩展),某些平台相关字符(圆形数字、罗马数字等)只能由 CP932 处理。
为什么会出现乱码
字符损坏的根本原因很简单:写入文件时使用的字符编码与读取文件时使用的字符编码不匹配。
例如,当Web应用程序以UTF-8导出CSV文件,用户用Excel打开时会出现乱码。这是因为在日本语环境中,Excel默认将文件解释为Shift_JIS(CP932)。
BOM(字节顺序标记)的作用
BOM 是添加在文件开头的多字节标记,用于标示字符编码。UTF-8 的 BOM 是 3 字节:<code>0xEF 0xBB 0xBF</code>。
<strong>要在Excel中正确打开UTF-8 CSV文件,需要BOM</strong>这是重要的一点。在Excel中打开没有BOM的UTF-8 CSV会被解释为Shift_JIS,导致字符乱码。
// PHP で BOM 付き UTF-8 CSV を出力する例
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="data.csv"');
// BOM を出力
echo "\xEF\xBB\xBF";
$fp = fopen('php://output', 'w');
fputcsv($fp, ['名前', 'メール', '部署']);
fputcsv($fp, ['田中太郎', 'tanaka@example.com', '開発部']);
fclose($fp);
# Python で BOM 付き UTF-8 CSV を出力する例
import csv
with open('data.csv', 'w', encoding='utf-8-sig', newline='') as f:
writer = csv.writer(f)
writer.writerow(['名前', 'メール', '部署'])
writer.writerow(['田中太郎', 'tanaka@example.com', '開発部'])
但是,BOM也有需要注意的地方。某些程序或shell脚本会将BOM视为无效字符,可能导致错误。对于API响应或程序处理的CSV文件,最好不要附加BOM。
换行码问题
除了 CSV 乱码外,另一个常见的问题是换行符代码的差异。
- <strong>CRLF</strong>(<code>\r\n</code>) — Windows 标准
- <strong>LF</strong>(<code>\n</code>) — Linux / macOS 标准
- <strong>CR</strong>(<code>\r</code>) — 旧版 Mac OS(现在几乎不使用)
RFC 4180 规定 CSV 的换行符应该是 CRLF。但实际上,许多工具可以无问题地处理仅含 LF 的 CSV 文件。Excel 和某些遗留系统更容易出现问题。
命令行工具便于检查换行码。
# file コマンドで確認
file data.csv
# 出力例: data.csv: UTF-8 Unicode (with BOM) text, with CRLF line terminators
# xxd で先頭バイトを確認(BOM の有無)
xxd data.csv | head -3
实用解决方案图表
以下是根据CSV预期用途的最优配置总结。
| 用途 | 字符编码 | BOM | 换行码 |
|---|---|---|---|
| 在 Excel 中打开 | UTF-8 | 有 | CRLF |
| 程序处理 | UTF-8 | 无 | LF |
| 遗留系统集成 | Shift_JIS (CP932) | 无 | CRLF |
| API 响应 | UTF-8 | 无 | LF |
测试 CSV 文件
要验证您的应用程序能否正确处理各种字符编码的 CSV 文件,请使用 DevLab 中的测试文件。
- <a href="/ja/files/encoding/">按字符编码划分的 CSV 测试文件</a> — UTF-8 (BOM 有/无)、Shift_JIS、EUC-JP 等
- <a href="/ja/files/newline/">按换行符代码分类的测试文件</a> — CRLF、LF、CR 各种文件
- <a href="/ja/files/csv/">CSV 测试文件列表</a> — 各种大小的 CSV 文件
总结
CSV字符编码问题可以通过正确理解三个关键因素来可靠地解决:字符编码、BOM(字节序标记)和行结束符。对于Excel,标准做法是使用带BOM的UTF-8和CRLF行结束符;对于程序处理,则使用不带BOM的UTF-8和LF行结束符。使用DevLab提供的各种测试文件,验证您的应用程序是否能正确处理每种模式。
本文中可用的测试文件
- → <a href="/ja/files/encoding/" class="text-primary-600 dark:text-primary-400 hover:underline">按字符编码分类的 CSV 测试文件列表(UTF-8 / Shift_JIS / EUC-JP)</a>
- → <a href="/ja/files/csv/" class="text-primary-600 dark:text-primary-400 hover:underline">CSV 测试文件列表</a>
相关文章
- → <a href="/ja/blog/file-format-quick-reference/" class="text-primary-600 dark:text-primary-400 hover:underline">开发者文件格式快速参考</a>
- → <a href="/ja/blog/wordpress-upload-limit-fix/" class="text-primary-600 dark:text-primary-400 hover:underline">提高 WordPress 上传限制的 5 种方法</a>