Django中如何生成临时Excel文件并返回至浏览器
Django生成临时Excel文件并返回浏览器的解决方案
方案一:内存中生成Excel(推荐,无磁盘文件残留)
直接通过BytesIO在内存中生成Excel文件,无需创建服务器磁盘临时文件,性能更优:
import pandas as pd from django.http import HttpResponse from io import BytesIO def export_wallet_view(request): # 1. 构造数据(替换为你实际的行数据逻辑,比如从数据库查询) csv_headers = ['Id', 'Name'] rows = [ {'Id': 1, 'Name': 'Wallet 1'}, {'Id': 2, 'Name': 'Wallet 2'} # 这里添加你的实际行数据 ] df = pd.DataFrame(rows, columns=csv_headers) # 2. 在内存中生成Excel output = BytesIO() with pd.ExcelWriter(output, engine='openpyxl') as writer: df.to_excel(writer, sheet_name='Wallets', index=False) output.seek(0) # 将文件指针移到开头,方便读取 # 3. 构造响应返回 response = HttpResponse( output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) response['Content-Disposition'] = 'attachment; filename="wallet.xlsx"' return response
方案二:保留原有CSV生成逻辑,转Excel临时文件
如果不想修改原有写CSV的逻辑,可先生成临时CSV,再转成Excel临时文件,最后清理所有临时文件:
import tempfile import pandas as pd from django.http import FileResponse import os def export_wallet_view(request): # 原有CSV生成逻辑 tmp_csv = tempfile.NamedTemporaryFile(delete=False, suffix='.csv', encoding='utf-8-sig') try: with open(tmp_csv.name, 'w', encoding="utf-8-sig") as fi: csv_headers = ['Id', 'Name'] fi.write(';'.join(csv_headers)) fi.write('\n') # 写入你的行数据(替换为实际逻辑) fi.write('1;Wallet 1\n') fi.write('2;Wallet 2\n') # 读取CSV到DataFrame(注意指定分隔符为;) df = pd.read_csv(tmp_csv.name, sep=';') # 创建Excel临时文件 tmp_excel = tempfile.NamedTemporaryFile(delete=False, suffix='.xlsx') try: df.to_excel(tmp_excel.name, sheet_name='Wallets', index=False) # 构造响应 response = FileResponse(open(tmp_excel.name, 'rb')) response['Content-Disposition'] = 'attachment; filename="wallet.xlsx"' response['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' return response finally: # 清理Excel临时文件 os.unlink(tmp_excel.name) finally: # 清理CSV临时文件 os.unlink(tmp_csv.name)
关键注意事项
- Content-Type设置:必须指定为
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,让浏览器识别为Excel文件 - 文件名后缀:
Content-Disposition中的文件名要改为.xlsx - 临时文件清理:使用
finally块确保临时文件被删除,避免服务器磁盘占用 - 分隔符处理:如果原有CSV用分号分隔,读取时必须指定
sep=';',否则Pandas会默认用逗号解析导致数据错误
内容的提问来源于stack exchange,提问作者gilvictor
相关产品推荐
相关产品推荐

