first commit
This commit is contained in:
83
app/export_xlsx.py
Normal file
83
app/export_xlsx.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import Alignment, Font, PatternFill, Border, Side
|
||||
|
||||
|
||||
def build_export(result: dict) -> bytes:
|
||||
wb = Workbook()
|
||||
thin = Border(
|
||||
left=Side(style="thin", color="D9D1C3"),
|
||||
right=Side(style="thin", color="D9D1C3"),
|
||||
top=Side(style="thin", color="D9D1C3"),
|
||||
bottom=Side(style="thin", color="D9D1C3"),
|
||||
)
|
||||
head = PatternFill("solid", fgColor="12233D")
|
||||
head_font = Font(color="F4EFE6", bold=True)
|
||||
wrap = Alignment(wrap_text=True, vertical="center")
|
||||
|
||||
first = True
|
||||
for g in result["groups"]:
|
||||
for t in g["targets"]:
|
||||
title = f"{g['group']}-{t['name']}"[:31]
|
||||
ws = wb.active if first else wb.create_sheet(title)
|
||||
if first:
|
||||
ws.title = title
|
||||
first = False
|
||||
ws.append(
|
||||
["班级", "测算人数", "最近一次在线", "滤波期望", "下达指标", "保底下界", "冲刺上界", "相对最近一次"]
|
||||
)
|
||||
for cell in ws[1]:
|
||||
cell.fill = head
|
||||
cell.font = head_font
|
||||
for row in t["classes"]:
|
||||
ws.append(
|
||||
[
|
||||
row["class_name"],
|
||||
row["n"],
|
||||
row["current"],
|
||||
row["expected"],
|
||||
row["assigned"],
|
||||
row["floor"],
|
||||
row["stretch"],
|
||||
row["delta"],
|
||||
]
|
||||
)
|
||||
ws.append([])
|
||||
ws.append(["说明:下达指标为预估中位水平,班级应努力超越该人数。保底/冲刺来自模拟分布的约20%/80%分位。"])
|
||||
|
||||
ws = wb.create_sheet("学生明细")
|
||||
exams = result["exams"]
|
||||
headers = ["学号", "姓名", "班级", "方向", "学籍", "选科"]
|
||||
headers += [f"{e}-排名" for e in exams]
|
||||
# collect target names
|
||||
tcols = []
|
||||
for g in result["groups"]:
|
||||
for t in g["targets"]:
|
||||
tcols.append((g["group"], t["id"], f"{g['group']}-{t['name']}概率"))
|
||||
headers += [c[2] for c in tcols]
|
||||
headers += ["滤波水平", "预测方差"]
|
||||
ws.append(headers)
|
||||
for cell in ws[1]:
|
||||
cell.fill = head
|
||||
cell.font = head_font
|
||||
cell.alignment = wrap
|
||||
for s in result["students"]:
|
||||
row = [s["sid"], s["name"], s["class_name"], s["group"], s.get("status") or "", s.get("subjects") or ""]
|
||||
ranks = s.get("ranks") or []
|
||||
for i, _e in enumerate(exams):
|
||||
row.append(ranks[i] if i < len(ranks) else None)
|
||||
for gname, tid, _ in tcols:
|
||||
if s["group"] == gname:
|
||||
row.append((s.get("probs") or {}).get(tid))
|
||||
else:
|
||||
row.append(None)
|
||||
row.append(s.get("pred_mean"))
|
||||
row.append(s.get("pred_var"))
|
||||
ws.append(row)
|
||||
|
||||
bio = BytesIO()
|
||||
wb.save(bio)
|
||||
return bio.getvalue()
|
||||
Reference in New Issue
Block a user