excel file returned

This commit is contained in:
Jean-Marie Place 2021-09-12 09:31:07 +02:00
parent 7f63ab222b
commit c8872bd220
2 changed files with 433 additions and 548 deletions

View File

@ -70,7 +70,7 @@ def send_from_flask(data, filename, mime=scu.XLSX_MIMETYPE):
response = make_response(data) response = make_response(data)
response.headers['Content-Type'] = mime response.headers['Content-Type'] = mime
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
return response
def send_excel_file(request, data, filename, mime=scu.XLSX_MIMETYPE): def send_excel_file(request, data, filename, mime=scu.XLSX_MIMETYPE):
"""publication fichier. """publication fichier.

View File

@ -76,6 +76,9 @@ from app.scodoc.TrivialFormulator import TrivialFormulator
_ = lambda x: x # sans babel _ = lambda x: x # sans babel
_l = _ _l = _
COORD = "Coordonnées"
SEQ = "Continue"
class PlacementForm(FlaskForm): class PlacementForm(FlaskForm):
TOUS = "Tous" TOUS = "Tous"
@ -87,9 +90,7 @@ class PlacementForm(FlaskForm):
wtforms.validators.DataRequired("indiquez le format du fichier attendu"), wtforms.validators.DataRequired("indiquez le format du fichier attendu"),
], ],
) )
surveillants = StringField( surveillants = StringField("Surveillants", validators=[])
"Surveillants", validators=[wtforms.validators.DataRequired("Test")]
)
batiment = StringField("Batiment") batiment = StringField("Batiment")
salle = StringField("Salle") salle = StringField("Salle")
nb_rangs = SelectField( nb_rangs = SelectField(
@ -97,7 +98,7 @@ class PlacementForm(FlaskForm):
) )
etiquetage = RadioField( etiquetage = RadioField(
"Numérotation", "Numérotation",
choices=["Continue", "Coordonnées"], choices=[SEQ, COORD],
validators=[ validators=[
wtforms.validators.DataRequired("indiquez le style de numérotation"), wtforms.validators.DataRequired("indiquez le style de numérotation"),
], ],
@ -177,7 +178,17 @@ def placement_eval_selectetuds(evaluation_id):
) )
form.set_evaluation_infos(evaluation_id) form.set_evaluation_infos(evaluation_id)
if form.validate_on_submit(): if form.validate_on_submit():
return _exec_placement(form) # calcul et generation du fichier runner = PlacementRunner(form)
if not runner.check_placement():
return (
"""<h2>Génération du placement impossible pour %s</h2>
<p>(vérifiez que le semestre n'est pas verrouillé et que vous
avez l'autorisation d'effectuer cette opération)</p>
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
"""
% runner.__dict__
)
return runner._exec_placement() # calcul et generation du fichier
# return flask.redirect(url_for("scodoc.index")) # return flask.redirect(url_for("scodoc.index"))
H = [html_sco_header.sco_header(init_jquery_ui=True)] H = [html_sco_header.sco_header(init_jquery_ui=True)]
H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id)) H.append(sco_evaluations.evaluation_describe(evaluation_id=evaluation_id))
@ -187,141 +198,133 @@ def placement_eval_selectetuds(evaluation_id):
return "\n".join(H) + "<p>" + F return "\n".join(H) + "<p>" + F
def _exec_placement(form): class PlacementRunner:
def __init__(self, form):
"""Calcul et génération du fichier sur la base des données du formulaire""" """Calcul et génération du fichier sur la base des données du formulaire"""
d = { self.evaluation_id = form["evaluation_id"].data
"evaluation_id": form["evaluation_id"].data, self.etiquetage = form["etiquetage"].data
"etiquetage": form["etiquetage"].data, self.surveillants = form["surveillants"].data
"surveillants": form["surveillants"].data, self.batiment = form["batiment"].data
"batiment": form["batiment"].data, self.salle = form["salle"].data
"salle": form["salle"].data, self.nb_rangs = form["nb_rangs"].data
"nb_rangs": form["nb_rangs"].data, self.file_format = form["file_format"].data
"groups_ids": form["groups"].data, self.groups_ids = form["groups"].data
} self.eval_data = sco_evaluations.do_evaluation_list(
d["eval_data"] = sco_evaluations.do_evaluation_list( {"evaluation_id": self.evaluation_id}
{"evaluation_id": d["evaluation_id"]}
)[0] )[0]
# Check access (admin, respformation, and responsable_id) self.cnx = ndb.GetDBConnexion()
d["current_user"] = current_user self.groups = sco_groups.listgroups(self.groups_ids)
d["moduleimpl_id"] = d["eval_data"]["moduleimpl_id"] self.gr_title_filename = sco_groups.listgroups_filename(self.groups)
if not sco_permissions_check.can_edit_notes(d["current_user"], d["moduleimpl_id"]):
return """<h2>Génération du placement impossible pour %s</h2>
<p>(vérifiez que le semestre n'est pas verrouillé et que vous
avez l'autorisation d'effectuer cette opération)</p>
<p><a href="moduleimpl_status?moduleimpl_id=%s">Continuer</a></p>
""" % (
d["current_user"].user_name,
d["module_id"],
)
d["cnx"] = ndb.GetDBConnexion()
d["groups"] = sco_groups.listgroups(d["groups_ids"])
d["gr_title_filename"] = sco_groups.listgroups_filename(d["groups"])
# gr_title = sco_groups.listgroups_abbrev(d['groups']) # gr_title = sco_groups.listgroups_abbrev(d['groups'])
d["moduleimpl_data"] = sco_moduleimpl.do_moduleimpl_list( self.current_user = current_user
moduleimpl_id=d["moduleimpl_id"] self.moduleimpl_id = self.eval_data["moduleimpl_id"]
self.moduleimpl_data = sco_moduleimpl.do_moduleimpl_list(
moduleimpl_id=self.moduleimpl_id
)[0] )[0]
d["Mod"] = sco_edit_module.do_module_list( self.Mod = sco_edit_module.do_module_list(
args={"module_id": d["moduleimpl_data"]["module_id"]} args={"module_id": self.moduleimpl_data["module_id"]}
)[0] )[0]
d["sem"] = sco_formsemestre.get_formsemestre( self.sem = sco_formsemestre.get_formsemestre(
d["moduleimpl_data"]["formsemestre_id"] self.moduleimpl_data["formsemestre_id"]
) )
d["evalname"] = "%s-%s" % ( self.evalname = "%s-%s" % (
d["Mod"]["code"], self.Mod["code"],
ndb.DateDMYtoISO(d["eval_data"]["jour"]), ndb.DateDMYtoISO(self.eval_data["jour"]),
) )
if d["eval_data"]["description"]: if self.eval_data["description"]:
d["evaltitre"] = d["eval_data"]["description"] self.evaltitre = self.eval_data["description"]
else: else:
d["evaltitre"] = "évaluation du %s" % d["eval_data"]["jour"] self.evaltitre = "évaluation du %s" % self.eval_data["jour"]
d["desceval"] = [ self.desceval = [
["%s" % d["sem"]["titreannee"]], ["%s" % self.sem["titreannee"]],
["Module : %s - %s" % (d["Mod"]["code"], d["Mod"]["abbrev"])], ["Module : %s - %s" % (self.Mod["code"], self.Mod["abbrev"])],
["Surveillants : %(surveillants)s" % d], ["Surveillants : %s" % self.surveillants],
["Batiment : %(batiment)s - Salle : %(salle)s" % d], ["Batiment : %(batiment)s - Salle : %(salle)s" % self.__dict__],
["Controle : %s (coef. %g)" % (d["evaltitre"], d["eval_data"]["coefficient"])], [
"Controle : %s (coef. %g)"
% (self.evaltitre, self.eval_data["coefficient"])
],
] # une liste de liste de chaines: description de l'evaluation ] # une liste de liste de chaines: description de l'evaluation
d["plan"] = _repartition(d)
if form["file_format"].data == "xls": def check_placement(self):
return _production_xls(d) # Check access (admin, respformation, and responsable_id)
return sco_permissions_check.can_edit_notes(
self.current_user, self.moduleimpl_id
)
def _exec_placement(self):
self._repartition()
if self.file_format == "xls":
return self._production_xls()
else: else:
return _production_pdf(d) return self._production_pdf()
def _repartition(self):
def _repartition(d):
""" """
Calcule le placement. retourne une liste de couples ((nom, prenom), position) Calcule le placement. retourne une liste de couples ((nom, prenom), position)
""" """
# Construit liste des etudiants # Construit liste des etudiants et les réparti
d["groups"] = sco_groups.listgroups(d["groups_ids"]) self.groups = sco_groups.listgroups(self.groups_ids)
d["listetud"] = _build_listetud(d) self.listetud = self._build_listetud()
return _affectation_places(d) self.plan = self._affectation_places()
def _build_listetud(self):
def _build_listetud(d): if None in [g["group_name"] for g in self.groups]: # tous les etudiants
if None in [g["group_name"] for g in d["groups"]]: # tous les etudiants
getallstudents = True getallstudents = True
gr_title_filename = "tous" gr_title_filename = "tous"
else: else:
getallstudents = False getallstudents = False
etudids = sco_groups.do_evaluation_listeetuds_groups( etudids = sco_groups.do_evaluation_listeetuds_groups(
d["evaluation_id"], self.evaluation_id,
d["groups"], self.groups,
getallstudents=getallstudents, getallstudents=getallstudents,
include_dems=True, include_dems=True,
) )
listetud = [] # liste de couples (nom,prenom) listetud = [] # liste de couples (nom,prenom)
for etudid in etudids: for etudid in etudids:
# infos identite etudiant (xxx sous-optimal: 1/select par etudiant) # infos identite etudiant (xxx sous-optimal: 1/select par etudiant)
ident = sco_etud.etudident_list(d["cnx"], {"etudid": etudid})[0] ident = sco_etud.etudident_list(self.cnx, {"etudid": etudid})[0]
# infos inscription # infos inscription
inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( inscr = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
{ {
"etudid": etudid, "etudid": etudid,
"formsemestre_id": d["moduleimpl_data"]["formsemestre_id"], "formsemestre_id": self.moduleimpl_data["formsemestre_id"],
} }
)[0] )[0]
if inscr["etat"] != "D": if inscr["etat"] != "D":
nom = ident["nom"].upper() nom = ident["nom"].upper()
prenom = ident["prenom"].lower().capitalize() prenom = ident["prenom"].lower().capitalize()
listetud.append((nom, prenom)) etudid = ident["etudid"]
listetud.append((nom, prenom, etudid))
random.shuffle(listetud) random.shuffle(listetud)
return listetud return listetud
def _affectation_places(self):
def _affectation_places(d):
plan = [] plan = []
if d["etiquetage"] == "continu": if self.etiquetage == SEQ:
distributeur = _DistributeurContinu() distributeur = _DistributeurContinu()
else: else:
distributeur = _Distributeur2D(d["nb_rangs"]) distributeur = _Distributeur2D(self.nb_rangs)
for etud in d["listetud"]: for etud in self.listetud:
plan.append((etud, distributeur.suivant())) plan.append((etud, distributeur.suivant()))
return plan return plan
def _production_xls(self):
def _production_xls(d): filename = scu.make_filename(
breakpoint() "placement_%s_%s%s"
filename = scu.make_filename("placement_%(evalname)s_%(gr_title_filename)s{scu.XLSX_SUFFIX}" % d) % (self.evalname, self.gr_title_filename, scu.XLSX_SUFFIX)
xls = _excel_feuille_placement(
d["eval_data"],
d["desceval"],
d["listetud"],
d["nb_rangs"],
d["batiment"],
d["salle"],
d["etiquetage"],
) )
xls = self._excel_feuille_placement()
return sco_excel.send_from_flask(xls, filename) return sco_excel.send_from_flask(xls, filename)
def _production_pdf(self):
def _production_pdf(d): pdf_title = self.desceval
pdf_title = d["desceval"]
pdf_title += ( pdf_title += (
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s" % d["eval_data"] "Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
% self.eval_data
) )
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % d filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % self
titles = { titles = {
"nom": "Nom", "nom": "Nom",
"prenom": "Prenom", "prenom": "Prenom",
@ -329,41 +332,25 @@ def _production_pdf(d):
"ligne": "Ligne", "ligne": "Ligne",
"place": "Place", "place": "Place",
} }
nbcolumns = int(columns) nb_rangs = int(self.nb_rangs)
if numbering == "coordinate": if self.etiquetage == COORD:
columns_ids = ["nom", "prenom", "colonne", "ligne"] columns_ids = ["nom", "prenom", "colonne", "ligne"]
else: else:
columns_ids = ["nom", "prenom", "place"] columns_ids = ["nom", "prenom", "place"]
# etudiants
line = 1
col = 1
orderetud = []
for etudid in listetud:
if numbering == "coordinate":
orderetud.append((etudid[0], etudid[1], col, line))
else:
orderetud.append((etudid[0], etudid[1], col + (line - 1) * nbcolumns))
if col == nbcolumns:
col = 0
line += 1
col += 1
rows = [] rows = []
orderetud.sort() for etud in sorted(plan, key=lambda etud: etud[0][0]): # sort by name
for etudid in orderetud: if self.etiquetage == COORD:
if numbering == "coordinate":
rows.append( rows.append(
{ {
"nom": etudid[0], "nom": etud[0][0],
"prenom": etudid[1], "prenom": etud[0][1],
"colonne": etudid[2], "colonne": etud[1][0],
"ligne": etudid[3], "ligne": etud[1][1],
} }
) )
else: else:
rows.append({"nom": etudid[0], "prenom": etudid[1], "place": etudid[2]}) rows.append({"nom": etud[0][0], "prenom": etud[0][1], "place": etud[1]})
tab = GenTable( tab = GenTable(
titles=titles, titles=titles,
@ -381,30 +368,26 @@ def _production_pdf(d):
t = tab.make_page(format="pdf", with_html_headers=False, REQUEST=REQUEST) t = tab.make_page(format="pdf", with_html_headers=False, REQUEST=REQUEST)
return t return t
def _one_header(self, ws):
def _one_header(ws, numbering, styles): cells = [
cells = [] ws.make_cell("Nom", self.styles["2bi"]),
if numbering == "coordinate": ws.make_cell("Prénom", self.styles["2bi"]),
cells.append(ws.make_cell("Nom", styles["2bi"])) ]
cells.append(ws.make_cell("Prénom", styles["2bi"])) if self.etiquetage == COORD:
cells.append(ws.make_cell("Colonne", styles["2bi"])) cells.append(ws.make_cell("Colonne", self.styles["2bi"]))
cells.append(ws.make_cell("Ligne", styles["2bi"])) cells.append(ws.make_cell("Ligne", self.styles["2bi"]))
else: else:
cells.append(ws.make_cell("Nom", styles["2bi"])) cells.append(ws.make_cell("Place", self.styles["2bi"]))
cells.append(ws.make_cell("Prénom", styles["2bi"]))
cells.append(ws.make_cell("Place", styles["2bi"]))
return cells return cells
def _headers(self, ws, nb_listes):
def _headers(ws, numbering, styles, nb_listes):
cells = [] cells = []
for _ in range(nb_listes): for _ in range(nb_listes):
cells += _one_header(ws, numbering, styles) cells += self._one_header(ws)
cells.append(ws.make_cell("")) cells.append(ws.make_cell(""))
ws.append_row(cells) ws.append_row(cells)
def _make_styles(self, ws0, ws1):
def _make_styles(ws0, ws1):
# polices # polices
font0 = Font(name="Calibri", bold=True, size=12) font0 = Font(name="Calibri", bold=True, size=12)
font1b = copy(font0) font1b = copy(font0)
@ -426,7 +409,9 @@ def _make_styles(ws0, ws1):
border2m = Border(top=side_thin, bottom=side_thin) border2m = Border(top=side_thin, bottom=side_thin)
border2r = Border(top=side_thin, bottom=side_thin, right=side_thin) border2r = Border(top=side_thin, bottom=side_thin, right=side_thin)
border2l = Border(left=side_thin, top=side_thin, bottom=side_thin) border2l = Border(left=side_thin, top=side_thin, bottom=side_thin)
border2b = Border(left=side_thin, top=side_thin, bottom=side_thin, right=side_thin) border2b = Border(
left=side_thin, top=side_thin, bottom=side_thin, right=side_thin
)
# alignements # alignements
align_center_center = Alignment(horizontal="center", vertical="center") align_center_center = Alignment(horizontal="center", vertical="center")
@ -440,7 +425,7 @@ def _make_styles(ws0, ws1):
) )
# styles # styles
styles = { self.styles = {
"titres": sco_excel.excel_make_style(font_name="Arial", bold=True, size=12), "titres": sco_excel.excel_make_style(font_name="Arial", bold=True, size=12),
"1t": ws0.excel_make_composite_style( "1t": ws0.excel_make_composite_style(
font=font0, alignment=align_center_center, border=border1t font=font0, alignment=align_center_center, border=border1t
@ -458,7 +443,10 @@ def _make_styles(ws0, ws1):
font=font1i, alignment=align_center_center, border=border2b font=font1i, alignment=align_center_center, border=border2b
), ),
"2bi": ws1.excel_make_composite_style( "2bi": ws1.excel_make_composite_style(
font=font2bi, alignment=align_center_center, border=border2b, fill=pattern font=font2bi,
alignment=align_center_center,
border=border2b,
fill=pattern,
), ),
"2l": ws1.excel_make_composite_style( "2l": ws1.excel_make_composite_style(
font=font2, alignment=align_left_center, border=border2l font=font2, alignment=align_left_center, border=border2l
@ -473,157 +461,83 @@ def _make_styles(ws0, ws1):
font=font2, alignment=align_right_center, border=border2r font=font2, alignment=align_right_center, border=border2r
), ),
} }
return styles
def _init_lines(self, maxlines):
def _init_lines(maxlines):
return [ return [
[] for _ in range(maxlines) [] for _ in range(maxlines)
] # lines[no_ligne] -> liste des cellules de la ligne (no_lignes de 1..maxlines ] # lines[no_ligne] -> liste des cellules de la ligne (no_lignes de 1..maxlines
def _write_lines(self, ws, lines):
def _write_lines(ws, lines):
for line in lines: for line in lines:
ws.append_row(line) ws.append_row(line)
def _titres(self, ws):
def _titres(ws, description, evaluation, building, room, styles):
dt = time.strftime("%d/%m/%Y a %Hh%M") dt = time.strftime("%d/%m/%Y a %Hh%M")
ws.append_single_cell_row( ws.append_single_cell_row(
"Feuille placement etudiants éditée le %s" % dt, styles["titres"] "Feuille placement etudiants éditée le %s" % dt, self.styles["titres"]
) )
for line, desceval in enumerate(description): for line, desceval in enumerate(self.desceval):
if line in [1, 4, 7]: if line in [1, 4, 7]:
ws.append_blank_row() ws.append_blank_row()
ws.append_single_cell_row(desceval[0], styles["titres"]) ws.append_single_cell_row(desceval[0], self.styles["titres"])
ws.append_single_cell_row( ws.append_single_cell_row(
"Date : %s - Horaire : %s à %s" "Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
% (evaluation["jour"], evaluation["heure_debut"], evaluation["heure_fin"]), % self.eval_data,
styles["titres"], self.styles["titres"],
)
ws.append_single_cell_row(
"Date : %s - Horaire : %s à %s"
% (evaluation["jour"], evaluation["heure_debut"], evaluation["heure_fin"]),
styles["titres"],
) )
def _feuille0(self, ws0, space):
def _feuille0( self._titres(ws0)
ws0,
description,
evaluation,
styles,
numbering,
listetud,
nbcolumns,
building,
room,
space,
):
_titres(ws0, description, evaluation, building, room, styles)
# entetes colonnes - feuille0 # entetes colonnes - feuille0
cells = [ws0.make_cell()] cells = [ws0.make_cell()]
for col in range(nbcolumns): for col in range(self.nb_rangs):
cells.append(ws0.make_cell("colonne %s" % (col + 1), styles["2b"])) cells.append(ws0.make_cell("colonne %s" % (col + 1), self.styles["2b"]))
ws0.append_row(cells) ws0.append_row(cells)
# etudiants
line = 1
col = 1
linetud = []
orderetud = []
placementetud = []
for etudid in listetud:
linetud.append(etudid)
if numbering == "coordinate":
orderetud.append((etudid[0], etudid[1], col, line))
else:
orderetud.append((etudid[0], etudid[1], col + (line - 1) * nbcolumns))
if col == nbcolumns:
placementetud.append(linetud)
linetud = []
col = 0
line += 1
col += 1
if len(linetud) > 0:
placementetud.append(linetud)
# etudiants - feuille0 # etudiants - feuille0
place = 1 place = 1
for rang, linetud in enumerate(placementetud, start=1): for rang, linetud in enumerate(self.plan, start=1):
# Chaque rang est affiché sur 3 lignes xlsx (notées A, B, C) # Chaque rang est affiché sur 3 lignes xlsx (notées A, B, C)
# ligne A: le nom, ligne B: le prénom, ligne C: un espace ou la place # ligne A: le nom, ligne B: le prénom, ligne C: un espace ou la place
cells_a = [ws0.make_cell(rang, styles["2b"])] cells_a = [ws0.make_cell(rang, self.styles["2b"])]
cells_b = [ws0.make_cell("", styles["2b"])] cells_b = [ws0.make_cell("", self.styles["2b"])]
cells_c = [ws0.make_cell("", styles["2b"])] cells_c = [ws0.make_cell("", self.styles["2b"])]
row = 14 # premieère ligne de signature row = 14 # premieère ligne de signature
for etudid in linetud: for etudid in linetud:
cells_a.append(ws0.make_cell(etudid[0], styles["1t"])) cells_a.append(ws0.make_cell(etudid[0], self.styles["1t"]))
cells_b.append(ws0.make_cell(etudid[1], styles["1m"])) cells_b.append(ws0.make_cell(etudid[1], self.styles["1m"]))
if numbering == "coordinate": if self.etiquetage == COORD:
cell_c = ws0.make_cell("", styles["1bb"]) cell_c = ws0.make_cell("", self.styles["1bb"])
else: else:
cell_c = ws0.make_cell("place %s" % place, styles["1bb"]) cell_c = ws0.make_cell("place %s" % place, self.styles["1bb"])
cells_c.append(cell_c) cells_c.append(cell_c)
ws0.set_row_dimension_height(row, space / 25) ws0.set_row_dimension_height(row, space / 25)
row += 3 row += 3
place = place + 1 place = place + 1
if col == nbcolumns: if col == self.nb_rangs:
ws0.append_row(cells_a) ws0.append_row(cells_a)
ws0.append_row(cells_b) ws0.append_row(cells_b)
ws0.append_row(cells_c) ws0.append_row(cells_c)
cells_a = [ws0.make_cell(rang, styles["2b"])] cells_a = [ws0.make_cell(rang, self.styles["2b"])]
cells_b = [ws0.make_cell("", styles["2b"])] cells_b = [ws0.make_cell("", self.styles["2b"])]
cells_c = [ws0.make_cell("", styles["2b"])] cells_c = [ws0.make_cell("", self.styles["2b"])]
# publication du rang final incomplet # publication du rang final incomplet
ws0.append_row(cells_a) ws0.append_row(cells_a)
ws0.append_row(cells_b) ws0.append_row(cells_b)
ws0.append_row(cells_c) ws0.append_row(cells_c)
ws0.set_row_dimension_height(row, space / 25) ws0.set_row_dimension_height(row, space / 25)
def _next_page(ws):
def _compute_ordretud(listetud, nbcolumns, numbering):
orderetud = []
line = 1
col = 1
for etudid in listetud:
if numbering == "coordinate":
orderetud.append((etudid[0], etudid[1], col, line))
else:
orderetud.append(
(etudid[0], etudid[1], "%s" % (col + (line - 1) * nbcolumns))
)
col += 1
if col > nbcolumns:
col = 1
line += 1
orderetud.sort()
return orderetud
def _next_page(ws):
pass pass
def _feuille1(self, ws, maxlines):
def _feuille1(
ws,
description,
evaluation,
styles,
numbering,
maxlines,
nbcolumns,
building,
room,
listetud,
):
# etudiants - feuille1 # etudiants - feuille1
# structuration: # structuration:
# 1 page = maxlistes listes # 1 page = maxlistes listes
# 1 liste = 3 ou 4 colonnes(excel) (selon numbering) et (maximum maxlines) lignes # 1 liste = 3 ou 4 colonnes(excel) (selon numbering) et (maximum maxlines) lignes
maxlistes = 2 # nombre de listes par page maxlistes = 2 # nombre de listes par page
# computes excel columns widths # computes excel columns widths
if numbering == "coordinate": if self.etiquetage == COORD:
gabarit = [16, 18, 6, 6, 2] gabarit = [16, 18, 6, 6, 2]
else: else:
gabarit = [16, 18, 12, 2] gabarit = [16, 18, 12, 2]
@ -631,65 +545,58 @@ def _feuille1(
for _ in range(maxlistes): for _ in range(maxlistes):
widths += gabarit widths += gabarit
ws.set_column_dimension_width(value=widths) ws.set_column_dimension_width(value=widths)
nb_etu_restant = len(listetud) nb_etu_restant = len(self.listetud)
_titres(ws, description, evaluation, building, room, styles) self._titres(ws)
nb_listes = min( nb_listes = min(
maxlistes, nb_etu_restant // maxlines + 1 maxlistes, nb_etu_restant // maxlines + 1
) # nombre de colonnes dans la page ) # nombre de colonnes dans la page
_headers(ws, numbering, styles, nb_listes) self._headers(ws, nb_listes)
# construction liste alphabétique # construction liste alphabétique
# Affichage # Affichage
lines = _init_lines(maxlines) lines = self._init_lines(maxlines)
orderetud = _compute_ordretud(listetud, nbcolumns, numbering)
line = 0 line = 0
col = 0 col = 0
for etudid in orderetud: for etud in sorted(self.plan, key=lambda etud: etud[0][0]):
# check for skip of list or page # check for skip of list or page
if col > 0: # add a empty cell between lists if col > 0: # add a empty cell between lists
lines[line].append(ws.make_cell()) lines[line].append(ws.make_cell())
lines[line].append(ws.make_cell(etudid[0], styles["2l"])) lines[line].append(ws.make_cell(etud[0][0], self.styles["2l"]))
lines[line].append(ws.make_cell(etudid[1], styles["2m1"])) lines[line].append(ws.make_cell(etud[0][1], self.styles["2m1"]))
if numbering == "coordinate": if self.etiquetage == COORD:
lines[line].append(ws.make_cell(etudid[2], styles["2m2"])) lines[line].append(ws.make_cell(etud[1][0], self.styles["2m2"]))
lines[line].append(ws.make_cell(etudid[3], styles["2r"])) lines[line].append(ws.make_cell(etud[1][1], self.styles["2r"]))
else: else:
lines[line].append(ws.make_cell(etudid[2], styles["2r"])) lines[line].append(ws.make_cell(etud[1], self.styles["2r"]))
line = line + 1 line = line + 1
if line >= maxlines: # fin de liste if line >= maxlines: # fin de liste
col = col + 1 col = col + 1
line = 0 line = 0
if col >= maxlistes: # fin de page if col >= maxlistes: # fin de page
_write_lines(ws, lines) self._write_lines(ws, lines)
lines = _init_lines(maxlines) lines = self._init_lines(maxlines)
col = 0 col = 0
ws.append_blank_row() ws.append_blank_row()
nb_etu_restant -= maxlistes * maxlines nb_etu_restant -= maxlistes * maxlines
nb_listes = min( nb_listes = min(
maxlistes, nb_etu_restant // maxlines + 1 maxlistes, nb_etu_restant // maxlines + 1
) # nombre de colonnes dans la page ) # nombre de colonnes dans la page
_headers(ws, numbering, styles, nb_listes) self._headers(ws, nb_listes)
_write_lines(ws, lines) self._write_lines(ws, lines)
def _excel_feuille_placement(self):
def _excel_feuille_placement(
evaluation,
description,
listetud,
columns,
building,
room,
numbering,
):
"""Genere feuille excel pour placement des etudiants. """Genere feuille excel pour placement des etudiants.
E: evaluation (dict) E: evaluation (dict)
lines: liste de tuples lines: liste de tuples
(etudid, nom, prenom, etat, groupe, val, explanation) (etudid, nom, prenom, etat, groupe, val, explanation)
""" """
breakpoint()
sem_preferences = sco_preferences.SemPreferences() sem_preferences = sco_preferences.SemPreferences()
space = sem_preferences.get("feuille_placement_emargement") space = sem_preferences.get("feuille_placement_emargement")
maxlines = sem_preferences.get("feuille_placement_positions") maxlines = sem_preferences.get("feuille_placement_positions")
nbcolumns = int(columns) nb_rangs = int(self.nb_rangs)
column_width_ratio = 1 / 250 # changement d unités entre pyExcelerator et openpyxl column_width_ratio = (
1 / 250
) # changement d unités entre pyExcelerator et openpyxl
wb = ScoExcelBook() wb = ScoExcelBook()
@ -697,41 +604,19 @@ def _excel_feuille_placement(
ws0 = wb.create_sheet(SheetName0) ws0 = wb.create_sheet(SheetName0)
# ajuste largeurs colonnes (unite inconnue, empirique) # ajuste largeurs colonnes (unite inconnue, empirique)
width = 4500 * column_width_ratio width = 4500 * column_width_ratio
if nbcolumns > 5: if nb_rangs > 5:
width = 22500 * column_width_ratio // nbcolumns width = 22500 * column_width_ratio // nb_rangs
ws0.set_column_dimension_width("A", 750 * column_width_ratio) ws0.set_column_dimension_width("A", 750 * column_width_ratio)
for col in range(nbcolumns): for col in range(nb_rangs):
ws0.set_column_dimension_width( ws0.set_column_dimension_width(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[col + 1: col + 2], width "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[col + 1 : col + 2], width
) )
SheetName1 = "Positions" SheetName1 = "Positions"
ws1 = wb.create_sheet(SheetName1) ws1 = wb.create_sheet(SheetName1)
styles = _make_styles(ws0, ws1) self._make_styles(ws0, ws1)
_feuille0( self._feuille0(ws0, space)
ws0, self._feuille1(ws1, maxlines)
description,
evaluation,
styles,
numbering,
listetud,
nbcolumns,
building,
room,
space,
)
_feuille1(
ws1,
description,
evaluation,
styles,
numbering,
maxlines,
nbcolumns,
building,
room,
listetud,
)
return wb.generate() return wb.generate()