C#导出CSV文件时如何正确写入含逗号字段避免列错位
C#导出CSV含逗号错位修复方案
不需要更换分隔符,遵循RFC 4180标准CSV格式规则对字段做转义即可,兼容Excel、WPS等所有主流表格软件的解析逻辑,转义规则如下:
- 若字段内容包含逗号、换行符、双引号任意一种特殊字符,将整个字段用半角双引号
"包裹 - 若字段内容本身包含半角双引号,将每个双引号替换为两个连续的双引号做转义
原有代码只需要新增一个通用字段转义方法,拼接字段时统一调用转义即可,修复后的完整代码如下:
public string dataToCsv(Dictionary<string, List<string>> data, long qty, string segment) { string dateToday = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); string user = Environment.UserName; var pathToCsv = "C:/Users/" + user + "/Documents/"+ segment + "-" + dateToday + ".csv"; StringBuilder sb = new StringBuilder(); // 写入表头,对列名做转义 string header = string.Join(",", data.Select(d => EscapeCsvField(d.Key))); sb.AppendLine(header); // 逐行写入数据 for (int i = 0; i < qty; i++) { string line = string.Join(",", data.Select(d => { // 取当前行对应列的值,兼容列数据长度不足的场景 string val = d.Value.ElementAtOrDefault(i) ?? string.Empty; return EscapeCsvField(val); })); sb.AppendLine(line); } System.IO.File.WriteAllText(pathToCsv, sb.ToString(), Encoding.UTF8); return pathToCsv; } /// <summary> /// 按CSV标准规则转义单个字段 /// </summary> private string EscapeCsvField(string field) { if (string.IsNullOrEmpty(field)) return string.Empty; // 包含特殊字符时用双引号包裹,同时转义内部双引号 if (field.Contains(',') || field.Contains('"') || field.Contains('\n') || field.Contains('\r')) { return $"\"{field.Replace("\"", "\"\"")}\""; } // 无特殊字符直接返回原值 return field; }
核心改动点
- 新增
EscapeCsvField方法统一处理字段转义,除逗号外,同时兼容字段包含双引号、换行符的场景,覆盖所有可能导致列错位的特殊字符情况 - 写入文件时指定
Encoding.UTF8编码,避免中文内容乱码 - 取值时用
ElementAtOrDefault做边界兼容,避免某一列的列表长度小于传入的qty参数时触发索引越界异常 - 用
AppendLine替代手动拼接换行符,代码更简洁
不建议随意更换分隔符为制表符、分号等其他符号:不同区域设置下的表格软件对非标准分隔符的识别逻辑不一致,很容易出现打开时所有内容挤在第一列的问题,按标准转义是兼容性最好的方案。
内容的提问来源于stack exchange,提问作者Jesus Favela
相关产品推荐
相关产品推荐

