def get_sheet_data(self, sheet, convert_float: bool) -> List[List[Scalar]]: """ Parse an ODF Table into a list of lists """ from odf.table import ( CoveredTableCell, TableCell, TableRow, ) covered_cell_name = CoveredTableCell().qname table_cell_name = TableCell().qname cell_names = {covered_cell_name, table_cell_name} sheet_rows = sheet.getElementsByType(TableRow) empty_rows = 0 max_row_len = 0 table: List[List[Scalar]] = [] for i, sheet_row in enumerate(sheet_rows): sheet_cells = [x for x in sheet_row.childNodes if x.qname in cell_names] empty_cells = 0 table_row: List[Scalar] = [] for j, sheet_cell in enumerate(sheet_cells): if sheet_cell.qname == table_cell_name: value = self._get_cell_value(sheet_cell, convert_float) else: value = self.empty_value column_repeat = self._get_column_repeat(sheet_cell) # Queue up empty values, writing only if content succeeds them if value == self.empty_value: empty_cells += column_repeat else: table_row.extend([self.empty_value] * empty_cells) empty_cells = 0 table_row.extend([value] * column_repeat) if max_row_len < len(table_row): max_row_len = len(table_row) row_repeat = self._get_row_repeat(sheet_row) if self._is_empty_row(sheet_row): empty_rows += row_repeat else: # add blank rows to our table table.extend([[self.empty_value]] * empty_rows) empty_rows = 0 for _ in range(row_repeat): table.append(table_row) # Make our table square for row in table: if len(row) < max_row_len: row.extend([self.empty_value] * (max_row_len - len(row))) return table
def creerCelluleRecouverte(self): """une cellule fusionnee hz de 3 c'est : - 1 cellule normale - 2 cellules recouvertes la cellule recouverte c'est une covered...""" return CoveredTableCell()
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))
def par_classe(classes, fileout): ods = OpenDocumentSpreadsheet() style_civilite = Style(parent=ods.automaticstyles, name='col_civilite', family='table-column') TableColumnProperties(parent=style_civilite, columnwidth='1cm') style_nom = Style(parent=ods.automaticstyles, name='col_nom', family='table-column') TableColumnProperties(parent=style_nom, columnwidth='4.5cm') style_date = Style(parent=ods.automaticstyles, name='col_date', family='table-column') TableColumnProperties(parent=style_date, columnwidth='3.2cm') style_internat = Style(parent=ods.automaticstyles, name='col_internat', family='table-column') TableColumnProperties(parent=style_internat, columnwidth='3.2cm') style_classe = Style(parent=ods.automaticstyles, name='col_classe', family='table-column') TableColumnProperties(parent=style_classe, columnwidth='3.2cm') style_etat_voeu = Style(parent=ods.automaticstyles, name='col_etat_voeu', family='table-column') TableColumnProperties(parent=style_etat_voeu, columnwidth='4cm') style_titre = Style(parent=ods.automaticstyles, name='cell_titre', family='table-cell') TextProperties(parent=style_titre, fontweight='bold', fontsize='14pt') ParagraphProperties(parent=style_titre, textalign='center') style_ligne_titre = Style(parent=ods.automaticstyles, name='ligne_titre', family='table-row') TableRowProperties(parent=style_ligne_titre, rowheight='8mm') style_entete = Style(parent=ods.automaticstyles, name='cell_entete', family='table-cell') TextProperties(parent=style_entete, fontweight='bold') number_style_date_format = odf.number.DateStyle(parent=ods.automaticstyles, name='date_number') odf.number.Day(parent=number_style_date_format, style='long') odf.number.Text(parent=number_style_date_format, text="/") odf.number.Month(parent=number_style_date_format, style='long') odf.number.Text(parent=number_style_date_format, text="/") odf.number.Year(parent=number_style_date_format, style='long') style_date_format = Style(parent=ods.automaticstyles, name='cell_date', family='table-cell', datastylename=number_style_date_format) for classe in classes: table = Table(name=str(classe)) table.addElement(TableColumn(stylename=style_civilite)) # Sexe table.addElement(TableColumn(stylename=style_nom)) # Nom table.addElement(TableColumn(stylename=style_nom)) # Prénom table.addElement( TableColumn(stylename=style_date)) # Date de naissance table.addElement(TableColumn(stylename=style_internat)) # Internat table.addElement(TableColumn(stylename=style_etat_voeu)) # État vœu table.addElement(TableColumn(stylename=style_nom)) # E-mail table.addElement(TableColumn(stylename=style_nom)) # Téléphone table.addElement(TableColumn(stylename=style_nom)) # Mobile # En-tête de la feuille tr = TableRow(parent=table, stylename=style_ligne_titre) cell = TableCell(parent=tr, numbercolumnsspanned=9, numberrowsspanned=1, valuetype='string', stylename=style_titre) cell.addElement(P(text=str(classe))) CoveredTableCell(parent=tr, numbercolumnsrepeated=8) tr = TableRow(parent=table) TableCell(parent=tr) # Sexe P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Nom") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Prénom") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Date de naissance") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Internat") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="État Parcoursup") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="E-mail") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Téléphone") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Mobile") for etudiant in classe.admissions().order_by('nom'): tr = TableRow() table.addElement(tr) TableCell(parent=tr, valuetype='string').addElement( P(text=etudiant.get_sexe_display())) TableCell(parent=tr, valuetype='string').addElement(P(text=etudiant.nom)) TableCell(parent=tr, valuetype='string').addElement(P(text=etudiant.prenom)) cell = TableCell(valuetype='date', datevalue=str(etudiant.date_naissance), stylename=style_date_format) cell.addElement(P(text=etudiant.date_naissance)) tr.addElement(cell) cell = TableCell(valuetype='string') if etudiant.proposition_actuelle.internat: cell.addElement(P(text="Interne")) tr.addElement(cell) TableCell(parent=tr, valuetype='string').addElement( P(text=etudiant.proposition_actuelle.get_etat_display())) TableCell(parent=tr, valuetype='string').addElement(P(text=etudiant.email)) TableCell(parent=tr, valuetype='string').addElement( P(text=etudiant.telephone)) TableCell(parent=tr, valuetype='string').addElement( P(text=etudiant.telephone_mobile)) ods.spreadsheet.addElement(table) # Liste générale pour l'infirmerie table = Table(name="Infirmerie") ods.spreadsheet.addElement(table) table.addElement(TableColumn(stylename=style_civilite)) # Sexe table.addElement(TableColumn(stylename=style_nom)) # Nom table.addElement(TableColumn(stylename=style_nom)) # Prénom table.addElement(TableColumn(stylename=style_classe)) # Classe table.addElement(TableColumn(stylename=style_date)) # Date de naissance table.addElement(TableColumn(stylename=style_internat)) # Internat # En-tête de la feuille tr = TableRow(parent=table, stylename=style_ligne_titre) cell = TableCell(parent=tr, numbercolumnsspanned=9, numberrowsspanned=1, valuetype='string', stylename=style_titre) cell.addElement(P(text="Liste de tous les étudiants admis")) tr = TableRow(parent=table) TableCell(parent=tr) # Sexe P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Nom") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Prénom") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Classe") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Date de naissance") P(parent=TableCell(parent=tr, valuetype='string', stylename=style_entete), text="Internat") for etudiant in Etudiant.objects.filter( proposition_actuelle__isnull=False, proposition_actuelle__date_demission__isnull=True).order_by( 'nom', 'prenom'): tr = TableRow(parent=table) TableCell(parent=tr, valuetype='string').addElement( P(text=etudiant.get_sexe_display())) TableCell(parent=tr, valuetype='string').addElement(P(text=etudiant.nom)) TableCell(parent=tr, valuetype='string').addElement(P(text=etudiant.prenom)) TableCell(parent=tr, valuetype='string').addElement( P(text=str(etudiant.proposition_actuelle.classe))) cell = TableCell(valuetype='date', datevalue=str(etudiant.date_naissance), stylename=style_date_format) cell.addElement(P(text=etudiant.date_naissance)) tr.addElement(cell) cell = TableCell(valuetype='string') if etudiant.proposition_actuelle.internat: cell.addElement(P(text="Interne")) tr.addElement(cell) ods.write(fileout)
def write_covered_cell(self): self._row.addElement(CoveredTableCell())
def fusion_mentions(etudiant, jury, attestation): # Création du tableau des résultats. On trie les mentions par ordre # inverse de position car, plus bas, l'ajout au tableau se fait avec # insertBefore, avec pour paramètre l'élément immédiatement après # l'intitulé du groupe. Par conséquent, les lignes placées en bas # doivent être ajoutées en premier. mentions = Mention.objects.filter(etudiant=etudiant, jury=jury).annotate( position=Min('grille_lignes__position')).order_by('-position') groupes_mentions = GrilleGroupeLignes.objects.filter( lignes__mention__etudiant=etudiant, lignes__mention__jury=jury).order_by( 'position', 'libelle').values_list('libelle', flat=True).distinct() for table_resultats in attestation.getElementsByType(Table): if table_resultats.getAttrNS(odf.namespaces.TABLENS, 'name') != 'enseignements': continue # Insertion de la ligne donnant le titre de la formation ligne = TableRow(parent=table_resultats) P(text=nom_formation(jury), parent=TableCell(parent=ligne, stylename='enseignements.C1', numbercolumnsspanned=3), stylename='Filière_20_ECTS') CoveredTableCell(parent=ligne, numbercolumnsrepeated=2) # On prépare les en-têtes des groupes de lignes odf_groupes = {} for groupe in groupes_mentions: # On évite les doublons éventuels sur les libellés (qui # pourraient intervenir car le queryset groupes_mentions # peut renvoyer le même libellé pour des champs position # distincts). if groupe in odf_groupes: continue ligne = TableRow(parent=table_resultats) odf_groupes[groupe] = ligne P(text=str(groupe), parent=TableCell(parent=ligne, stylename='enseignements.C1', numbercolumnsspanned=3), stylename='Groupe_20_ECTS') CoveredTableCell(parent=ligne, numbercolumnsrepeated=2) # Lorsqu'il existe des mentions présentes dans des groupes et # d'autres hors groupes, on prévoit un pour ces dernières un # intitulé générique associé au groupe de clé "None". if odf_groupes and mentions.filter(grille_lignes__groupe__isnull=True, globale=False): ligne = TableRow(parent=table_resultats) odf_groupes[None] = ligne P(text="Autres", parent=TableCell(parent=ligne, stylename='enseignements.C1', numbercolumnsspanned=3), stylename='Groupe_20_ECTS') CoveredTableCell(parent=ligne, numbercolumnsrepeated=2) # On ajoute les mentions au tableau mention_globale = None for mention in mentions: if mention.globale: mention_globale = mention continue if mention.mention is None or \ Mention.mention == Mention.MENTION_INSUFFISANT: continue # Si la ligne possède un groupe, elle est positionnée juste # après la ligne d'intitulé de ce groupe. try: groupe = mention.grille_lignes.first().groupe cle_groupe = groupe.libelle if groupe is not None else None ligne_nextsibling = odf_groupes[cle_groupe].nextSibling except Exception as e: ligne_nextsibling = None ligne = TableRow() table_resultats.insertBefore(ligne, ligne_nextsibling) P(text=mention.get_libelle_attestation(), parent=TableCell(parent=ligne, stylename='enseignements.A1'), stylename='Matière_20_ECTS') P(text=mention.credits if mention.credits > 0 else "−", parent=TableCell(parent=ligne, stylename='enseignements.A1'), stylename='Crédits_20_ECTS') P(text=(mention.get_mention_display() or "").capitalize(), parent=TableCell(parent=ligne, stylename='enseignements.C1'), stylename='Mention_20_ECTS') # Insertion de la mention globale if mention_globale is not None: ligne = TableRow(parent=table_resultats) P(text="Mention globale", parent=TableCell(parent=ligne, stylename='enseignements.A1'), stylename='Mention_20_globale_20_ECTS') P(text=mention_globale.credits, parent=TableCell(parent=ligne, stylename='enseignements.A1'), stylename='Crédits_20_ECTS') P(text=(mention_globale.get_mention_display() or "").capitalize(), parent=TableCell(parent=ligne, stylename='enseignements.C1'), stylename='Mention_20_ECTS')