用StringBuilder拼接CSV最稳,需预估容量、转义特殊字符、避免空格开头、统一用\r\n换行、显式指定UTF8编码并加BOM,字段顺序需显式控制,大文件应流式写入。

用 StringBuilder 拼接 CSV 最稳,别直接 string +
频繁字符串拼接会触发大量内存分配,List 一两千条数据就可能明显卡顿。用 StringBuilder 预估容量(比如每行平均 100 字符 × 行数),性能提升明显。
- 字段含逗号、换行或双引号时,必须用英文双引号包裹该字段,且内部双引号要转义为两个双引号(
"→"") - 整行不能以空格开头,否则 Excel 可能误判为公式(显示
#VALUE!) - 别用
Environment.NewLine写入文件——Windows 记事本认\r\n,但 Linux/macOS 工具更习惯\n;导出给用户下载时统一用\r\n更稳妥
File.WriteAllText 要指定 Encoding.UTF8,否则中文变乱码
默认编码是系统本地编码(如 Windows-1252),中文写进去就是问号或方块。即使你用的是 UTF-8 字符串,不显式传 Encoding.UTF8,File.WriteAllText 仍可能走默认编码。
- Excel 打开 UTF-8 CSV 有时不识别 BOM,加 BOM 更保险:
new UTF8Encoding(true) - 如果目标系统是旧版 Excel(尤其是 Mac Excel 2011),它只认 UTF-16 + BOM,这时得换用
Encoding.Unicode(即 UTF-16 LE) - 别用
File.WriteAllLines:它会在每行末尾自动加换行符,和你自己拼的换行冲突,导致空行
处理对象列表时,字段顺序靠 typeof(T).GetProperties() 不可靠
反射获取属性顺序取决于编译器和运行时,不是声明顺序,也不是字母序。导出列错位很常见。
- 显式定义字段顺序:用
[Index(0)]自定义特性,或传入IEnumerable<string> propertyNames参数 - 跳过只读属性(
CanWrite == false)和索引器(IsIndexer == true),否则取值时报TargetException - 对
null值统一转成空字符串,避免ToString()抛NullReferenceException
导出大文件(>10MB)别全加载进内存
用 StreamWriter 流式写入,配合 yield return 分批读取数据源,内存占用能压到几百 KB。
- 别把整个
List<T>一次性传进导出方法——改成接受IEnumerable<T>或IAsyncEnumerable<T> - 每写 1000 行调一次
sw.Flush(),防断电丢数据(尤其网络共享盘) - 文件路径含中文或特殊字符时,确保目录已存在,
Directory.CreateDirectory(Path.GetDirectoryName(filePath))别漏










