必须使用textfieldparser或csvhelper等标准解析器处理csv引号,禁用string.split;写入时按rfc 4180转义双引号为""并仅在必要时加引号,统一换行符与utf-8 bom编码。

CSV读取时引号被忽略或解析错乱
CSV标准要求:字段含逗号、换行符或双引号时,必须用双引号包裹;若字段内本身含双引号,则需转义为两个连续双引号("")。.NET原生TextFieldParser能自动处理这些规则,但很多人直接用string.Split(',')导致解析崩溃。
常见错误现象:"John ""The Boss"" Smith"被拆成三段、含换行的地址字段被误判为多行、逗号分隔的金额字段(如"1,234.56")被截断。
- 务必使用
Microsoft.VisualBasic.FileIO.TextFieldParser(即使项目是C#),它默认启用RFC 4180兼容模式 - 初始化后必须调用
SetDelimiters(",")并设置HasFieldsEnclosedInQuotes = true - 不要手动
Trim('"')——解析器已内置去引号逻辑,二次处理反而破坏转义
写入CSV时双引号未正确转义
手动生成CSV字符串时,仅在必要时加引号(比如字段含逗号/换行/引号),且内部引号必须替换成""。错误做法是“所有字段都加引号”或“只替换一次引号”。
示例:原始值He said "Hello" → 正确转义为"He said ""Hello"""(首尾各一个双引号,中间两个)。
- 用
string.Replace("\"", "\"\"")做预处理,再包裹",而非正则或子串拼接 - 检查是否含
\n或\r——这类字符必须进引号,否则破坏行结构 - 避免用
StringBuilder.AppendLine()直接写字段,应先组装单行字符串再写入
第三方库CsvHelper的EscapeQuotes配置陷阱
CsvHelper默认开启引号转义,但CsvConfiguration.Escape和CsvConfiguration.Quote若被误设,会导致双引号消失或重复输出。
典型问题:导出后Excel里显示John ""The Boss"" Smith变成John """The Boss""" Smith(多了一对引号)。
- 保持
configuration.Quote = '"'和configuration.Escape = '"'一致(即用双引号同时作包裹符和转义符) - 禁用自动引号(
configuration.ShouldQuote = (field, context) => false)会导致含逗号字段裸奔,不推荐 - 写入前调用
csv.WriteField(value)而非csv.WriteField(value.ToString()),防止ToString()引入意外格式
跨平台换行符与BOM导致Excel打不开
Windows记事本用\r\n,macOS/Linux用\n,而Excel for Mac对无BOM的UTF-8文件常乱码。直接File.WriteAllText(path, csvContent)可能埋雷。
- 写入时显式指定编码:
new StreamWriter(path, append: false, Encoding.UTF8)(UTF-8无BOM)或Encoding.UTF8带BOM需用new UTF8Encoding(encoderShouldEmitUTF8Identifier: true) - 行结束符统一用
Environment.NewLine,不要硬写"\r\n"——否则Linux服务器生成的文件在Windows Excel里会粘成一行 - 测试时用VS Code或Notepad++看实际换行符类型,别只信Excel的渲染结果










