我正在try 编写响应以允许下载报告.我通过数据库查询检索相关数据,并将其存储在内存中,以避免在服务器上生成不必要的文件.我目前面临的挑战是将CSV文件保存到一个压缩文件中.遗憾的是,我在这个问题上花了几个小时也没有找到令人满意的解决方案,我也不确定我可能犯下的具体错误.有问题的CSV文件大小约为40 MB.
这是我的FastAPI代码.我成功地将CSV文件保存在本地,其中的所有数据都是准确的.我还设法正确地创建了一个包含CSV的压缩文件.然而,FastAPI响应的行为与预期不符.下载后,它返回我的压缩错误
ZIP文件已损坏,或者存档出现意外结尾.
from fastapi import APIRouter, Depends
from sqlalchemy import text
from libs.auth_common import veryfi_admin
from libs.database import database
import csv
import io
import zipfile
from fastapi.responses import Response
router = APIRouter(
tags=['report'],
responses={404: {'description': 'not found'}}
)
@router.get('/raport', dependencies=[Depends(veryfi_admin)])
async def get_raport():
query = text(
"""
some query
"""
)
data_de = await database.fetch_all(query)
csv_buffer = io.StringIO()
csv_writer_de = csv.writer(csv_buffer, delimiter=';', lineterminator='\n')
csv_writer_de.writerow([
"id", "name", "date", "stock",
])
for row in data_de:
csv_writer_de.writerow([
row.id,
row.name,
row.date,
row.stock,
])
csv_buffer.seek(0)
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
zip_file.writestr("data.csv", csv_buffer.getvalue())
response = Response(content=zip_buffer.getvalue())
response.headers["Content-Disposition"] = "attachment; filename=data.zip"
response.headers["Content-Type"] = "application/zip"
response.headers["Content-Length"] = str(len(zip_buffer.getvalue()))
print("CSV Buffer Contents:")
print(csv_buffer.getvalue())
return response
这也是VUE3代码
const downloadReport = () => {
loading.value = true;
instance
.get(`/raport`)
.then((res) => {
const blob = new Blob([res.data], { type: "application/zip" });
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = "raport.zip";
link.click();
loading.value = false;
})
.catch(() => (loading.value = false));
};
<button @click="downloadReport" :disabled="loading">
Download Report
</button>
感谢您的理解,我在这个平台上提出了我的第一个问题.