导出 6 万行 CSV,服务端按 8192 字节切块往下写,下载后文件尾部每隔几行出现一个 �,用 Excel 打开提示编码错误,英文导出正常。碰到这种情况,我一般先确认改动有没有真的生效。

原因不复杂,UTF-8 一个汉字占三字节,按固定字节数切会把一个字符劈成两半,前后两块各自编码后都成了非法序列。按字节拼接再整体解码时,边界处的残片无法还原。

「流式导出乱码」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。

def gen():
    for line in rows:
        yield (line + '\n').encode('utf-8')
return StreamingResponse(gen(), media_type='text/csv')

权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

具体做法是,生成器按整行 encode 后 yield 不要在字节层面切块;让框架按 chunk 发送 不要自己拼固定长度缓冲区;下载后用 iconv 校验一遍 确认没有非法字节。

最后用这个标准收尾,重新下载的 CSV 用 iconv -f utf-8 校验通过,中文列没有替换字符,行数与导出条数一致。

作者 9823189