我有一段代码,可以将 csv 响应写入
StringIO()
对象。我通过端点返回此对象,并使用此输出生成将存储在服务器上的 csv 文件。
@app.post('/csv-data')
def get_csv(data: DataRequest):
if not data.headers:
raise HTTPException(status_code=400, detail="Headers cannot be empty")
if data.number_of_records <= 0:
raise HTTPException(status_code=400, detail="Number of requested records must be more than 0")
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
file_name = f"data_{timestamp}.csv"
file_path = os.path.join(STORAGE_DIR, file_name)
headers = [
{"name": header.name, "description": header.description, "sample_data": header.sample_data}
for header in data.headers
]
response = open_ai_interface.generate_data(headers, data.number_of_records)
output = StringIO()
csvwriter = csv.writer(output, quoting=csv.QUOTE_MINIMAL)
for row in response:
csvwriter.writerow(row.split(','))
output.seek(0)
with open(file_path, 'w') as f:
f.write(output.getvalue())
output.seek(0)
return StreamingResponse(output, media_type="text/csv", headers={"Content-Disposition": f"attachment; filename={file_name}"})
我面临的问题是生成的 .csv 文件在每条记录之间包含一条额外的行。当我通过浏览器或邮递员发送请求时,我得到的响应是记录之间的新行。 这让我假设可能有更好的方法将 csv 数据写入文件。我很感激建议
TextIOWrapper
的类似 csv.writer
的对象被记录为需要包含 newline=''
作为参数以防止 的翻译。 不幸的是,虽然 io.StringIO
有 newline
参数,但它并不像 TextIOWrapper
那样支持它:
字符串IO:
类似,只不过在将输出写入流时,如果 newline 为TextIOWrapper
,则在所有平台上换行符都将写为None
。\n
如果没有
newline=None
,csv.writer
会直接将其默认的“excel”方言(换行符为 \r\n
)写入流。 稍后,当将流写入文件时,在 Windows 系统上以 text 模式 (mode='r'
) 打开文件会将 \n
转换为 \r\n
,从而导致 \r\n
变为 \r\r\n
。 这是额外的换行符。
TL;DR:要修复,请使用
output = StringIO(newline=None)
。