如何通过JavaScript实现Flask文件下载并返回渲染模板?
实现Flask文件处理后返回模板并触发文件下载
问题背景
原Flask路由通过send_file直接返回处理后的文件,无法同时返回渲染的模板页面。需要通过JavaScript实现文件下载,让路由返回新模板的同时自动触发下载。
1. 修改Flask路由代码
将原路由中的send_file替换为返回模板,并将处理后的文件转为Base64字符串传递给模板:
import base64 # 新增导入 from datetime import datetime as dt from flask import render_template, request @app.route('/generatecleanbudgetfile', methods=['GET', 'POST']) def clean_budget(): app.logger.info('Budget Formatting request has started') try: if request.method == 'POST': file = request.files.get('data_file') if not file: app.logger.error('No file uploaded') return render_template('error_type.html', title='No file uploaded') file.seek(0) buffer = budget_cleaner(file) buffer.seek(0) # 将文件内容转为Base64字符串 file_data = base64.b64encode(buffer.getvalue()).decode('utf-8') filename = f'stripped_budget_{dt.today().strftime("%m.%d.%Y")}.xlsx' app.logger.info('Conversion Complete') # 返回成功模板,传递下载所需数据 return render_template( 'success_page.html', download_data=file_data, filename=filename, title='Budget Formatting Complete' ) # GET请求返回上传页面 return render_template('upload_budget.html') # 对应原HTML页面 except Exception as e: # 优化错误日志,避免file为None时报错 file_name = file.filename if file else 'unknown file' app.logger.error(f"Budget formatting failed on {file_name}: {str(e)}") return render_template('error_type.html', title='Unable to process uploaded budget')
2. 创建成功页面模板(success_page.html)
在模板中加入JavaScript逻辑,页面加载时自动触发文件下载,同时提供手动下载按钮:
{% extends "base.html" %} {% block content %} <div class="container mt-4"> <h2>预算文件格式化完成!</h2> <p class="mb-3">文件将自动开始下载,若未触发请点击下方按钮:</p> <button id="downloadBtn" class="btn btn-primary">下载处理后的预算文件</button> </div> <script> // 页面加载完成后自动触发下载 window.addEventListener('load', downloadFile); // 下载核心函数 function downloadFile() { const base64Data = "{{ download_data }}"; const fileName = "{{ filename }}"; const mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; // 将Base64转为Blob对象 const byteChars = atob(base64Data); const byteArrays = []; for (let i = 0; i < byteChars.length; i += 512) { const slice = byteChars.slice(i, i + 512); const byteNumbers = new Array(slice.length); for (let j = 0; j < slice.length; j++) { byteNumbers[j] = slice.charCodeAt(j); } byteArrays.push(new Uint8Array(byteNumbers)); } const blob = new Blob(byteArrays, { type: mimeType }); // 创建临时URL并触发下载 const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = fileName; document.body.appendChild(a); a.click(); // 清理资源 document.body.removeChild(a); URL.revokeObjectURL(url); } // 绑定手动下载按钮事件 document.getElementById('downloadBtn').addEventListener('click', downloadFile); </script> {% endblock %}
3. 原上传页面保持不变
原HTML代码无需修改,确保表单提交到/generatecleanbudgetfile即可。
内容的提问来源于stack exchange,提问作者Mike Mann
相关产品推荐
相关产品推荐

