如何将Flask中WTForms的form.data导出为XLSX文件
表单提交导出XLSX功能实现方案
先修复现有代码的已知问题
你当前的代码存在几个会直接导致报错的逻辑问题,需要先修正再做导出功能:
- 解决类名冲突:将
forms.py里的Entry表单类重命名为EntryForm,避免和models.py里的Entry数据库模型重名,路由导入时分开引入两个类。 - 修正数据库模型配置:删除Entry模型里除
id、SKU外所有字段的unique=True约束,否则同品牌、同颜色的商品重复提交会直接报数据库唯一键错误;将Kids_Sizes、Adult_Sizes字段类型从Integer改为String(100),用于存储多选框返回的多值拼接结果;补上缺失的Model字段:Model = db.Column(db.String(50), nullable=False),否则表单提交的型号数据无法存储。 - 移除表单类里的固定值定义:删除表单类下写死的
User = current_user、Date = date.strftime(xxx)、Time = date.strftime(xxx)类属性,这类动态值在路由提交逻辑里实时获取即可,类级别定义会导致时间在服务启动时就固定,不会随提交时间更新。 - 修正原entry路由的存库逻辑:你原来把Entry表单的数据往Post模型里存是错误的,Post模型只有博客文章相关字段,没有商品属性,提交后应该实例化Entry模型存数据。
依赖安装
执行命令安装Excel处理需要的库:
pip install pandas openpyxl
核心导出逻辑实现
在entry路由的表单验证通过分支里,完成数据校验后把表单数据整理成结构化字典,用pandas生成Excel内存流,直接返回给浏览器触发下载,不需要把文件存到服务器本地。
修正后的entry路由代码参考:
import io from datetime import datetime import pandas as pd from flask import send_file from flaskblog.models import Entry as EntryModel # 重命名导入避免和表单类冲突 from flaskblog.forms import EntryForm # 重命名后的表单类 # 其他原有路由保持不变 @app.route('/entry', methods=['GET', 'POST']) @login_required def entry(): form = EntryForm() if form.validate_on_submit(): # 整理表单提交的数据,和导出列一一对应 entry_data = { "提交用户ID": current_user.id, "提交时间": datetime.now(), "SKU": form.SKU.data, "是否父SKU": form.Parent.data, "品牌": form.Brand.data, "适用人群": form.Gender.data, "扣合方式": form.Closure.data, "型号": form.Model.data, "商品类型": form.Type.data, "主色": form.Colour.data, "生产国家": form.Country_Manu.data, "鞋面材质": form.Upper_Mat.data, "内衬材质": form.Lining_Mat.data, "内底材质": form.Insole_Mat.data, "跟高(cm)": form.Heel_Height.data, "重量(kg)": form.Weight.data, "高度(cm)": form.Height.data, "长度(cm)": form.Length.data, "厚度(cm)": form.Depth.data, "采购订单号": form.Purchase_Ord.data, "标签": form.Label.data, "儿童尺码": ",".join(form.Kids_Sizes.data), # 多选值转逗号拼接字符串 "成人尺码": ",".join(form.Adult_Sizes.data) } # 如果需要留存数据到数据库,打开下面三行注释即可 # new_entry = EntryModel(**entry_data) # db.session.add(new_entry) # db.session.commit() # 生成Excel内存流 df = pd.DataFrame([entry_data]) output = io.BytesIO() with pd.ExcelWriter(output, engine='openpyxl') as writer: df.to_excel(writer, index=False, sheet_name='商品清单') output.seek(0) # 将文件指针移到流开头 flash('商品清单生成成功', 'success') # 返回文件响应触发浏览器下载 return send_file( output, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', as_attachment=True, download_name=f'商品清单_{datetime.now().strftime("%Y%m%d%H%M%S")}.xlsx' ) return render_template('entry.html', title='Entry', form=form, legend='Entry')
补充说明
- 如果需要批量导出多条历史商品数据,只需要从数据库查询出对应结果,转成字典列表传入
pd.DataFrame()即可,逻辑和单条导出完全一致。 - 多选框字段如果需要拆分到多列存储,可以自行调整数据结构,把每个尺码单独作为一列存布尔值即可。
- 导出的Excel列名、顺序可以直接修改
entry_data字典的键顺序和名称自定义。
内容的提问来源于stack exchange,提问作者Sirico
相关产品推荐
相关产品推荐

