ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

fastapi: 把数据表导出成excel电子表格文件

2026/8/2 22:55:23 拓冰建站 浏览量
fastapi: 把数据表导出成excel电子表格文件

一,安装第三方库

$ pip install pandas

第二个库:

$ pip install openpyxl

二,代码

javascript

function get_selected_id() {// 1. 获取你的 form 元素 (假设 form 的 id 是 'myForm')const form = document.getElementById('myForm');console.log("form:", form)// 2. 找到该 form 下所有选中的 checkboxconst checkedBoxes = form.querySelectorAll('input[type="checkbox"][name="check-item"]:checked');console.log("checkedBoxes:", checkedBoxes)// 3. 将 NodeList 转换为数组,并提取 valueconst values = Array.from(checkedBoxes).map(checkbox => checkbox.value);console.log(values); // 输出类似: ["apple", "banana"]return values;
}//导出角色列表
function role_export(){var url = "{{ url_for('role_export') }}";var ids = get_selected_id();idstr = ''for(let i = 0; i < ids.length; i++) {console.log(ids[i]);if (idstr == '') {idstr = ids[i]} else {idstr = idstr+","+ids[i]}}var dest_url = url+"?ids="+idstrwindow.location.href = dest_url;
}

python:

# 做validator的form
class RoleExportForm(WTForm):#id = IntegerField('page', [validators.NumberRange(min=1)], default=0)# ,validators=[DataRequired()], min_entries=1ids = FieldList(IntegerField("ids",validators=[NumberRange(min=1,message="每个数字最小不能小于 1")]),min_entries=1)def validate_ids(self, field):# field.data 是一个列表,包含了所有提交上来的数据# 过滤掉 None 或空值,计算真正有效的条目数valid_entries = [v for v in field.data if v is not None]# 如果有效条目数小于 min_entries (这里是 1)if len(valid_entries) < 1:raise ValidationError("至少需要填写一项id!")  # 这里写你自定义的报错信息@router.get("/export",summary="角色数据导出")
async def role_export(request: Request,response: Response,db: AsyncSession = Depends(get_db)):# 得到参数get_data = request.query_paramsprint("get_data:", get_data)# form_data_dict = MultiDict()res = {}ids = []for key in get_data.keys():print("key:", key)# 用 .getlist(key) 把前端 append 的同名数组全部捞出来if key == 'ids':idsstr = get_data.get(key)idslist = idsstr.split(',')for value in idslist:print("value:", value)ids.append(int(value))res["ids"] = idsform = RoleExportForm(data=res)if form.validate() == False:error_str = get_error_message(form.errors)return ApiResponse.fail(response=response, code=400, status_code=400, message=error_str)# 查询数据raw_data = []for id in form.ids.data:print("id:", id)# 1. 查询用户是否存在stmt = select(Role).where(Role.id == id)result = await db.execute(stmt)role = result.scalars().first()if not role:continueraw_one = {'id': role.id,'name': role.name,}raw_data.append(raw_one)# 2. 将数据转为 Pandas 的 DataFrame,并映射表头为中文df = pd.DataFrame(raw_data)df.rename(columns={"id": "角色ID","name": "角色名字",}, inplace=True)# 3. 创建内存中的字节流对象(关键:避免写入服务器硬盘)buffer = io.BytesIO()# 4. 使用 ExcelWriter 将 DataFrame 写入这个内存 buffer# index=False 表示不需要把 Pandas 默认的 0,1,2 行索引导出去with pd.ExcelWriter(buffer, engine='openpyxl') as writer:df.to_excel(writer, index=False, sheet_name="员工薪酬表")# 5. 将指针移到 buffer 的起始位置,以便从头读取数据buffer.seek(0)# 6. 设置特殊的响应头,通知浏览器这是一个需要下载的文件附带文件名# 使用 URL 编码防止中文文件名变成乱码from urllib.parse import quotefilename = quote("角色数据表.xlsx")headers = {'Content-Disposition': f'attachment; filename="{filename}"; filename*=utf-8\'\'{filename}'}# 7. 通过 StreamingResponse 返回二进制流,指定 Excel 的 media_typereturn StreamingResponse(buffer,media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",headers=headers)

 

三,测试效果:

image