Latin-9导出CSV文件培养瓶

tjrkku2a  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(82)

我试图从数据库导出数据到CSV文件。导出完成得很完美,但是,我在数据库中有一些阿拉伯文本,在导出数据时,我得到拉丁文-9字符。如下所示。(* 我在Windows上 *)

在记事本中打开此CSV文件时,我可以看到正确的值

ID,Serial,City,Office
1,ASDF4321,مصر,مصر
2,FDSA1234,السعودية,السعودية
3,ASDF4321,مصر,مصر
4,FDSA1234,السعودية,السعودية

我的代码是:

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()
    mem.write(si.getvalue().encode())
    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)

如何导出到CSV文件并使其如下所示:

jtw3ybtb

jtw3ybtb1#

我设法解决了这个问题,我不得不添加byte order mark (BOM),这是一个Unicode字符,用于指示文件是以UTF-8编码的。它必须作为文件中的第一个字符添加。

@app.route("/export", methods=["GET", "POST"])
def export():
    si = StringIO()
    si.write("\ufeff") # This line
    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()
    mem.write(si.getvalue().encode())
    mem.seek(0)
    si.close()
    return send_file(
        mem, mimetype="text/csv", download_name="Export-File.csv", as_attachment=True
    )


使用"".encode("utf-8-sign")utf-8-sig编解码器将在开头预先挂起BOM。

@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()
    mem.write(si.getvalue().encode("utf-8-sig")) # Edit here
    mem.seek(0)
    si.close()
    return send_file(
        mem, mimetype="text/csv", download_name="Export-File.csv", as_attachment=True
    )

相关问题