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

生产环境(Gunicorn+Nginx)下Django应用Excel下载异常问题

问题解决思路

核心问题分析

生产环境下载Excel返回download.htm,本质是浏览器未正确识别响应的文件类型和下载指令,大概率是响应头配置错误或Nginx代理丢失关键头信息导致的。

针对性解决方案

1. 修正响应头的格式与类型

你更新后的视图函数存在两个关键错误:

  • Content-Type类型错误:.xlsx文件对应的MIME类型应为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,而非application/vnd.ms-excel(这是.xls文件的类型)
  • Content-Disposition格式错误:filename= "{}"中的空格会导致浏览器解析异常,需改为filename="{}"

修改后的视图代码(同时优化为内存生成Excel,避免磁盘操作问题):

@login_required
def download_estimate_excel_file(request, project_id, project_name):
    project_tnc_obj = ProjectTermsAndConditions.objects.filter(project=project_id)
    date_time_obj = datetime.now()
    current_date = date_time_obj.strftime('%x')
    current_time = date_time_obj.strftime('%X')

    # 处理文件名特殊字符,兼容多浏览器
    from urllib.parse import quote
    filename = f"{project_name}_{current_date.replace('/', '-')}_{current_time.replace(':', '-')}.xlsx"
    encoded_filename = quote(filename)

    # 改用BytesIO在内存生成Excel,无需临时文件
    from io import BytesIO
    output = BytesIO()
    workbook = ... # 你的openpyxl工作簿创建逻辑
    # ... 填充sheet内容的代码 ...
    workbook.save(output)
    output.seek(0)
    workbook.close()

    response = HttpResponse(
        output.getvalue(),
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )
    # 兼容不同浏览器的文件名解析规则
    response['Content-Disposition'] = f'attachment; filename="{filename}"; filename*=UTF-8\'\'{encoded_filename}'
    return response

2. 确保Nginx传递完整响应头

检查/etc/nginx/proxy_params文件,确保包含以下配置(没有则添加):

proxy_set_header Content-Disposition $sent_http_content_disposition;
proxy_set_header Content-Type $sent_http_content_type;

也可直接在项目的Nginx配置location /块中添加:

location / {
    include proxy_params;
    proxy_pass http://unix:/run/gunicorn.sock;
    # 新增两行,确保响应头完整传递
    proxy_set_header Content-Disposition $sent_http_content_disposition;
    proxy_set_header Content-Type $sent_http_content_type;
}

修改后重启Nginx:

sudo systemctl restart nginx

3. 移除HTML标签的download属性

当响应头已明确Content-Disposition: attachment时,HTML的download属性可能与服务器响应头冲突,建议移除:

<a href="{% url 'download_estimate_excel_file' project.id project.name %}" class="dropdown-item"> Download Excel </a>

额外优化建议

  • 避免磁盘文件操作:用BytesIO在内存直接生成Excel,既省去临时文件的创建/删除步骤,也不会出现文件读取与删除的竞态问题
  • 文件名转义:对包含空格、非ASCII字符的文件名进行URL编码,确保所有浏览器都能正确识别文件名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:09:16