SQL Server导出CSV中文乱码的根本原因是导出链路中UTF-8被系统默认按ANSI(如GBK/Windows-1252)解析,因SSMS“另存为”不支持编码选择且无BOM;可靠解法是用bcp加-f 65001参数导出带BOM的UTF-8文件,并配合字段引号与正确转义。

乱码不是Excel的问题,而是SQL Server导出链路中UTF-8被当成ANSI(GBK/Windows-1252)解析了——哪怕你数据库用的是utf8mb4或Chinese_PRC_CI_AS,导出环节没显式声明编码,Windows就默认按ANSI读。
SSMS“将结果另存为CSV”时中文变“???”
这是最常见也最容易被忽略的场景:右键查询结果 → “将结果另存为” → 选.csv → 打开就是乱码。根本原因是SSMS导出时不带BOM,也不指定编码,系统直接用记事本默认的ANSI写入文件。
- 别依赖“另存为”功能导出含中文的CSV,它不提供编码选择项
- 临时补救:用记事本打开该CSV → “另存为” → 编码选
ANSI(不是UTF-8)→ 再用Excel打开,能显示中文但可能丢生僻字 - 真正可靠的做法:改用
sqlcmd或bcp,并强制指定-f 65001(即UTF-8 with BOM)
bcp导出CSV必须加-f 65001且字段加引号
bcp本身不生成BOM,但加上-f 65001参数后,会输出带BOM的UTF-8文件,Excel双击就能正确识别。不加这个,即使内容是UTF-8,Excel仍大概率当ANSI读。
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
- 正确命令示例:
bcp "SELECT * FROM my_view" queryout "data.csv" -c -t"," -f 65001 -S localhost -T -
-c表示字符模式,-t","指定逗号分隔,-f 65001才是解决乱码的关键 - 如果字段含逗号、换行或双引号,必须配合
QUOTENAME()或在SQL里手动加引号,否则Excel列会错位 - 注意:
bcp不自动加表头,需用UNION ALL拼接一行字符串字段,且所有列要CAST成VARCHAR保持类型一致
PowerShell + Invoke-Sqlcmd导出时双引号转义失效
用Invoke-Sqlcmd | ConvertTo-Csv看似方便,但它生成的CSV不遵守RFC 4180:字段内出现"时不会转义成"",导致Excel解析断裂。
- 例如值
he said "hello"会被导出为"he said "hello"",Excel认作三个字段 - 解决方案:改用
Export-Csv -Encoding UTF8(PowerShell 6+),它会自动加BOM并转义双引号 - 旧版PowerShell(5.1)必须手动处理:
ForEach-Object { $_.Column -replace '"', '""' | ForEach-Object { '"' + $_ + '"' } } - 避免用
ConvertTo-Csv直接输出到文件,它默认用Unicode(UTF-16 LE),Excel识别不稳定
Excel导入CSV时编码选错导致列错位
很多人跳过导入向导,双击CSV——这会让Excel用系统默认编码(ANSI)解析UTF-8字节流,一个汉字被拆成两个“字符”,不仅乱码,列数也对不上。
- 正确流程:
数据选项卡 →从文本/CSV→ 选文件 → 左下角手动选65001: Unicode (UTF-8)→ 点加载 - 如果导入后第一列为空,说明原CSV有BOM但Excel误判了编码;进Power Query →
高级编辑器→ 删掉开头那行乱码(通常是#table前的不可见字符) - 别信“UTF-8-BOM”这种叫法,Excel里只认
65001编码ID,不是文件名后缀
BOM头和字段引号是两条硬性底线:缺一不可。前者管中文显示,后者管结构完整——少了任一个,你在Excel里看到的都不是原始数据,只是某种误读后的残影。

















