Django实现可获取下载路径与格式的IFC文件转换下载按钮功能
注意:受浏览器安全策略限制,后端服务无法直接读取用户本地磁盘的指定保存路径,正确实现逻辑是后端生成转换后的文件,返回文件流触发浏览器下载弹窗,由用户自主选择保存路径、修改文件名,以下是完整实现方案:
第一步:修改前端模板
在core/model_form_download.html里添加表单,提供自定义文件名输入、转换格式选择控件:
<form method="post"> {% csrf_token %} <div> <label>自定义文件名(可选):</label> <input type="text" name="custom_filename" placeholder="留空则使用原文件名"> </div> <div> <label>选择转换格式:</label> <select name="convert_format" required> <option value="xlsx">标准XLSX</option> <option value="filtered_xlsx">筛选版XLSX</option> <option value="json">JSON</option> </select> </div> <button type="submit">下载转换后文件</button> </form>
第二步:修改视图函数
from django.http import FileResponse from io import BytesIO import json def model_form_download(request): if request.method == 'POST': # 1. 从表单获取用户提交的参数 custom_filename = request.POST.get('custom_filename', '').strip() convert_format = request.POST.get('convert_format') # 2. 读取最近上传的IFC模型 last_model = Document.objects.latest("uploaded_at") last_model_name = last_model.document.name MODEL_DIR = Path(MEDIA_DIR) / last_model_name model = parser(MODEL_DIR) # 3. 处理文件名逻辑 base_name = Path(last_model_name).stem if not custom_filename else custom_filename # 给文件名加对应后缀 suffix_map = { 'xlsx': '.xlsx', 'filtered_xlsx': '_filtered.xlsx', 'json': '.json' } full_filename = base_name + suffix_map[convert_format] # 4. 根据格式生成对应的文件流(不用存本地磁盘,直接内存生成返回) buffer = BytesIO() if convert_format in ['xlsx', 'filtered_xlsx']: # 筛选版请根据你的parser返回结构调整对应取值逻辑 export_data = model[1] if convert_format == 'xlsx' else model[2] export_data.to_excel(buffer, index=False) elif convert_format == 'json': json.dump(model[1].to_dict('records'), buffer, ensure_ascii=False) # 把文件指针移到开头 buffer.seek(0) # 5. 返回文件响应,触发浏览器下载 response = FileResponse(buffer, as_attachment=True, filename=full_filename) return response return render(request, 'core/model_form_download.html')
实现说明
- 不需要获取用户本地保存路径:浏览器收到文件响应后会自动弹出下载框,用户可以自主选择保存位置、修改文件名
- 格式参数直接从POST请求的表单字段
convert_format获取,通过映射表匹配对应转换逻辑即可 - 采用内存流生成文件的方式,无需在服务器磁盘留存转换后的文件,节省存储空间;如果转换后的文件体积较大,可改用服务器临时目录存储生成的文件,返回响应后再定时清理临时文件即可
内容的提问来源于stack exchange,提问作者Bruno_BNF
相关产品推荐
相关产品推荐

