def colloscope_odf(request, classe): """ Affichage du colloscope d'une classe au format OpenDocument """ semaines = classe.semaine_set.order_by('debut') creneaux = classe.creneau_set.order_by('enseignement', 'jour', 'debut') colles = classe.colle_set.filter(semaine__in=semaines, creneau__in=creneaux) # On crée le dictionnaire qui à chaque créneau puis à chaque semaine # associe les groupes de colle colloscope = defaultdict(lambda: defaultdict(list)) for colle in colles: colloscope[colle.creneau][colle.semaine].append(colle) ods = OpenDocumentSpreadsheet() # Styles style_entete = Style(parent=ods.automaticstyles, name='cell_entete', family='table-cell') TextProperties(parent=style_entete, fontweight='bold') style_col_semaine = Style(parent=ods.automaticstyles, name='col_semaine', family='table-column') TableColumnProperties(parent=style_col_semaine, columnwidth='1cm') style_col_matiere = Style(parent=ods.automaticstyles, name='col_matiere', family='table-column') TableColumnProperties(parent=style_col_matiere, columnwidth='5cm') style_col_colleur = Style(parent=ods.automaticstyles, name='col_colleur', family='table-column') TableColumnProperties(parent=style_col_colleur, columnwidth='5cm') style_col_salle = Style(parent=ods.automaticstyles, name='col_salle', family='table-column') TableColumnProperties(parent=style_col_salle, columnwidth='2cm') table = Table(name=str(classe), parent=ods.spreadsheet) # Ajout des colonnes d'en-tête fixes entetes_fixes = ("ID", "Matière", "Colleur", "Jour", "Horaire", "Salle") table.addElement(TableColumn(stylename=style_col_semaine)) # ID table.addElement(TableColumn(stylename=style_col_matiere)) # Matière table.addElement(TableColumn(stylename=style_col_colleur)) # Colleur table.addElement(TableColumn()) # Jour table.addElement(TableColumn()) # Horaire table.addElement(TableColumn(stylename=style_col_salle)) # Salle # Ajout des colonnes d'en-tête des semaines for _ in semaines: table.addElement(TableColumn(stylename=style_col_semaine)) # Container pour les lignes d'en-tête th = TableHeaderRows(parent=table) # Ligne d'en-tête avec les semestres au-dessus des semaines tr = TableRow(parent=th) for entete in entetes_fixes: P(parent=TableCell(parent=tr, valuetype='string', numberrowsspanned=2, numbercolumnsspanned=1, stylename=style_entete), text=entete) # On doit savoir combien de semaines se trouvent sur chaque période # pour afficher les en-têtes sur le bon nombre de colonnes nb_semaines = dict([ ( periode[0], 0, ) for periode in constantes.PERIODE_CHOICES ]) for semaine in semaines: nb_semaines[semaine.periode] += 1 # Insertion des titres des périodes for periode_id, periode_nom in constantes.PERIODE_CHOICES: if nb_semaines[periode_id] > 0: P(parent=TableCell(parent=tr, valuetype='string', numbercolumnsspanned=nb_semaines[periode_id], numberrowsspanned=1, stylename=style_entete), text=periode_nom.capitalize()) CoveredTableCell(parent=tr, numbercolumnsrepeated=nb_semaines[periode_id] - 1) tr = TableRow(parent=th) # Ligne d'en-tête avec seulement les semaines # On doit placer des cellules vides pour les case d'en-tête situées # avant les semaines CoveredTableCell(parent=tr, numbercolumnsrepeated=len(entetes_fixes)) # Puis on ajoute les semaines for semaine in semaines: P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text=semaine.numero) # Colles par créneau for creneau in creneaux: tr = TableRow(parent=table) P(parent=TableCell(parent=tr, valuetype='float', value=creneau.pk), text=creneau.pk) P(parent=TableCell(parent=tr, valuetype='string'), text=creneau.matiere) P(parent=TableCell(parent=tr, valuetype='string'), text=creneau.colleur) P(parent=TableCell(parent=tr, valuetype='string'), text=creneau.get_jour_display()) P(parent=TableCell(parent=tr, valuetype='time', timevalue=creneau.debut.strftime("PT%HH%MM%SS")), text=creneau.debut.strftime("%H:%M")) P(parent=TableCell(parent=tr, valuetype='string'), text=creneau.salle) for semaine in semaines: groupes_texte = ','.join([str(c.groupe) for c in colloscope[creneau][semaine] if c.groupe]) cell = TableCell(parent=tr) if groupes_texte: cell.valuetype="string" P(parent=cell, text=groupes_texte) return OdfResponse(ods, filename="colloscope_{}.ods".format(classe.slug))