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

使用Django无法下载自定义Excel模板是什么原因?该如何实现下载功能?

问题排查与修正方案

现有代码的核心问题列表

  • 前端表单配置错误:
    • 提交按钮错误设置了两个type属性,type="button"会导致点击后不会触发表单提交
    • 表单action路径与urls配置不匹配,且method误设为GET,表单提交参数应走POST
    • action写死相对路径容易出错,应该用Django模板的url反向解析
  • 后端视图逻辑缺失:
    • create_template视图的POST分支没有任何业务逻辑,既没有校验表单,也没有生成Excel、返回下载响应的代码
    • Excel生成函数直接将文件写入服务器本地磁盘,没有将文件流返回给用户
    • 表单参数没有做格式转换:用户输入的sheet名、列名都是以符号分隔的字符串,没有拆分就直接遍历会得到单个字符,年份也没有生成起止区间的列表
  • 函数命名混淆:生成Excel的函数命名为create_form,和表单类名混淆,可读性差

修正后的完整代码

1. my_app/templates/my_app/create_template.html

{% extends "my_app/base.html" %}
{% block content %}
<form action="{% url 'my-create-template' %}" method="POST">
  {% csrf_token %}
  <h1>Create your template</h1>
  <div class="item">
    <table>
      {{ form.as_table }}
    </table>
    <p>提示:多个sheet名、列名请用英文逗号分隔</p>
  </div>
  <div class="btn-block">
    <input type="submit" value="Create and Download!"/>
  </div>
</form>
{% endblock content %}

2. my_app/views.py

from django.http import HttpResponse
from django.shortcuts import render
import xlsxwriter
from django.forms import Form, CharField, ChoiceField

def home(request):
    return render(request, 'my_app/home.html')

class TemplateForm(Form):
    doc_name = CharField(label='Document name')
    sheetnames = CharField(label='Sheetnames')
    choices = []
    for year in range (1900, 2050):
        choices.append( (year, year) )
    year1 = ChoiceField(label='Starting Year', initial=2021, choices=choices)
    year2 = ChoiceField(label='Ending Year', initial=2022, choices=choices)    
    row_names = CharField(label='Column names')

def create_template(request):
    if request.method == 'GET':
        form = TemplateForm()
        return render(request, 'my_app/create_template.html', {'form':form})
    # POST请求处理逻辑
    form = TemplateForm(request.POST)
    if form.is_valid():
        data = form.cleaned_data
        # 处理表单参数
        doc_name = data['doc_name']
        # 拆分sheet名,按英文逗号分割,去空格
        sheetnames = [i.strip() for i in data['sheetnames'].split(',') if i.strip()]
        # 生成年份区间列表
        start_year = int(data['year1'])
        end_year = int(data['year2'])
        years = list(range(start_year, end_year+1))
        # 拆分列名
        row_names = [i.strip() for i in data['row_names'].split(',') if i.strip()]

        # 生成HttpResponse对象,设置Excel对应的mime类型
        response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        # 设置响应头,指定下载文件名
        response['Content-Disposition'] = f'attachment; filename="{doc_name}_template.xlsx"'

        # 直接将Excel写入response对象,不需要存服务器本地
        workbook = xlsxwriter.Workbook(response)
        worksheet_introduction = workbook.add_worksheet("introduction")
        for sheet_name in sheetnames:
            worksheet_data = workbook.add_worksheet(sheet_name)
            worksheet_data.write_row(0, 1, years)
            worksheet_data.write_column(1, 0, row_names)
        workbook.close()
        return response
    # 表单校验失败返回表单页
    return render(request, 'my_app/create_template.html', {'form':form})

3. my_app/urls.py 无需修改,原有配置可正常使用

内容的提问来源于stack exchange,提问作者project.py

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:30:06