You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows系统下Flask导出CSV时阿拉伯文显示为Latin-9的解决方法

解决Flask导出CSV中阿拉伯文在Windows下显示为Latin-9乱码的问题

这个问题在Windows系统处理非英文CSV时特别常见——核心原因是Windows下多数CSV阅读器(比如Excel)默认不会自动识别无BOM的UTF-8编码,会改用系统默认的Latin-9(Windows-1252)编码解析内容;而记事本现在已经支持自动检测UTF-8,所以能正常显示阿拉伯文。

要解决这个问题,只需要给导出的CSV文件加上UTF-8 BOM(字节顺序标记),让Windows系统明确知道文件使用UTF-8编码。下面是两种简单的修改方式:

方案一:使用utf-8-sig编码(最简便)

Python的encode('utf-8-sig')会自动在字节流开头添加UTF-8 BOM标记,无需手动处理。只需要修改代码中写入BytesIO的那一行:

# 原代码
mem.write(si.getvalue().encode())
# 修改为
mem.write(si.getvalue().encode('utf-8-sig'))

方案二:手动写入UTF-8 BOM(更直观)

如果你希望明确控制BOM的写入流程,可以先手动写入BOM字节,再写入编码后的内容:

mem = BytesIO()
# 先写入UTF-8 BOM标记
mem.write(b'\xef\xbb\xbf')
# 再写入UTF-8编码的CSV内容
mem.write(si.getvalue().encode('utf-8'))
mem.seek(0)

修改后的完整代码

这里给出用方案一修改后的完整代码,确保阿拉伯文能在Windows下的Excel、WPS等软件中正常显示:

import csv
from io import BytesIO, StringIO

from flask import Flask, send_file
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__, instance_relative_config=True)

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.sqlite3"
db = SQLAlchemy(app)


class Device(db.Model):
    __tablename__ = "device"
    id = db.Column(db.Integer, primary_key=True)
    serial = db.Column(db.String(255), nullable=True)
    city = db.Column(db.String(255), nullable=True)
    office = db.Column(db.String(255), nullable=True)

    def __repr__(self):
        return f"<Device {self.serial!r}, {self.city!r}, {self.office!r}>"


with app.app_context():
    db.create_all()

    device1 = Device(serial="ASDF4321", city="مصر", office="مصر")
    device2 = Device(serial="FDSA1234", city="السعودية", office="السعودية")
    db.session.add(device1)
    db.session.add(device2)
    db.session.commit()


@app.route("/", methods=["GET"])
def index():
    return "Home"


@app.route("/export", methods=["GET", "POST"])
def export():
    si = StringIO()
    devices = Device.query.all()
    csvwriter = csv.writer(si, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL)
    csvwriter.writerow(["ID", "Serial", "City", "Office"])
    for i, device in enumerate(devices, start=1):
        csvwriter.writerow([i, device.serial, device.city, device.office])
    mem = BytesIO()
    # 关键修改:使用utf-8-sig编码自动添加BOM
    mem.write(si.getvalue().encode('utf-8-sig'))
    mem.seek(0)
    si.close()
    return send_file(
        mem, mimetype="text/csv", download_name="Export-File.csv", as_attachment=True
    )


if __name__ == "__main__":
    app.run(debug=True)

为什么这样能解决问题?

  • UTF-8 BOM(\xef\xbb\xbf)是一个特殊的字节序列,Windows系统的应用程序会识别这个标记,从而用UTF-8编码读取文件,而不是默认的Latin-9。
  • 记事本之所以能正常显示,是因为它现在支持自动检测无BOM的UTF-8编码,但Excel等办公软件还需要明确的BOM标记才能正确识别非英文内容。

内容的提问来源于stack exchange,提问作者Tes3awy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:31:14