[scodoc-devel] [SVN] Scolar : [1657] [PE] Un tab excel par tag (Cleo).

eviennet at lipn.univ-paris13.fr eviennet at lipn.univ-paris13.fr
Sam 1 Juil 12:26:03 CEST 2017


Une pièce jointe HTML a été nettoyée...
URL: https://listes.univ-paris13.fr/pipermail/scodoc-devel/attachments/20170701/9cb49bf0/attachment.htm 
-------------- section suivante --------------
Modified: branches/ScoDoc7/gen_tables.py
===================================================================
--- branches/ScoDoc7/gen_tables.py	2017-07-01 09:47:56 UTC (rev 1656)
+++ branches/ScoDoc7/gen_tables.py	2017-07-01 10:26:03 UTC (rev 1657)
@@ -41,6 +41,7 @@
 """
 
 import random
+from collections import OrderedDict
 
 # XML generation package (apt-get install jaxml)
 import jaxml
@@ -384,9 +385,9 @@
         H.append(self.html_next_section)
         return '\n'.join(H)
         
-    def excel(self):
+    def excel(self, wb=None):
         "Simple Excel representation of the table"
-        L = sco_excel.ScoExcelSheet( sheet_name=self.xls_sheet_name)
+        L = sco_excel.ScoExcelSheet( sheet_name=self.xls_sheet_name )
         style_bold = sco_excel.Excel_MakeStyle(bold=True)
         
         L.cells += self.xls_before_table
@@ -400,7 +401,7 @@
             L.append( [] ) # empty line        
             L.append( [self.origin] )
 
-        return L.gen_workbook() 
+        return L.gen_workbook(wb=wb)
     
     def text(self):
         "raw text representation of the table"
@@ -567,8 +568,28 @@
             log('make_page: format=%s' % format )
             raise ValueError('_make_page: invalid format')
 
+# -----
+class SeqGenTable() :
+    """Sequence de GenTable: permet de générer un classeur excel avec un tab par table.
+    L'ordre des tabs est conservé (1er tab == 1ere table ajoutée)
+    """
+    def __init__(self):
+        self.genTables = OrderedDict()
 
+    def add_genTable(self, name, gentable):
+        self.genTables[name] = gentable
 
+    def get_genTable(self, name):
+        return self.genTables.get(name)
+
+    def excel(self):
+        """Export des genTables dans un unique fichier excel avec plusieurs feuilles tagguées"""
+        book = sco_excel.Workbook() # Le fichier xls en devenir
+        for (name, gt) in self.genTables.items():
+            gt.excel(wb=book) # Ecrit dans un fichier excel
+        return book.savetostr()
+
+
 # ----- Exemple d'utilisation minimal.
 if __name__ == '__main__':
     T = GenTable( rows = [ { 'nom' : 'Toto', 'age' : 26 }, { 'nom' : 'Titi', 'age' : 21 } ],

Modified: branches/ScoDoc7/pe_jurype.py
===================================================================
--- branches/ScoDoc7/pe_jurype.py	2017-07-01 09:47:56 UTC (rev 1656)
+++ branches/ScoDoc7/pe_jurype.py	2017-07-01 10:26:03 UTC (rev 1657)
@@ -13,12 +13,17 @@
 # ----------------------------------------------------------
 
 
-try: from cStringIO import StringIO
-except: from StringIO import StringIO
+try:
+    from cStringIO import StringIO
+except:
+    try:
+        from StringIO import StringIO
+    except:
+        from io import StringIO
 from zipfile import ZipFile, BadZipfile
 import pprint
 
-from gen_tables import GenTable
+from gen_tables import GenTable, SeqGenTable
 
 import sco_codes_parcours #sco_codes_parcours.NEXT -> sem suivant
 import sco_report
@@ -46,14 +51,16 @@
     
     """
     # Variables de classe
-    PARCOURS = { 'S1': ['S1'], \
-                 'S2' : ['S2'], \
-                 'S3' : ['S3'], \
-                 'S4' : ['S4'], \
-                 '1A' : ['S1', 'S2'], \
-                 '2A' : ['S3', 'S4'], \
-                 '3S' : ['S1', 'S2', 'S3'], \
-                 '4S' : ['S1', 'S2', 'S3', 'S4'] }
+    PARCOURS = {
+        'S1': ['S1'], 
+        'S2' : ['S2'],
+        'S3' : ['S3'],
+        'S4' : ['S4'],
+        '1A' : ['S1', 'S2'],
+        '2A' : ['S3', 'S4'],
+        '3S' : ['S1', 'S2', 'S3'],
+        '4S' : ['S1', 'S2', 'S3', 'S4'],
+        }
     
     # *********************************************
     def __init__(self, context, semBase ):
@@ -130,7 +137,11 @@
             self.zipfile.writestr(filename, str(self.syntheseJury))
         
         filename = self.REPERTOIRE_EXPORT + "jurySyntheseDict_" + str(self.diplome) + '.xls'
-        self.zipfile.writestr(filename, self.table_syntheseJury().excel())
+        self.xls = self.table_syntheseJury(mode="singlesheet")
+        self.zipfile.writestr(filename, self.xls.excel()) #Fabrique 1 fichier excel résultat avec 1 seule feuille => trop gros
+        filename = self.REPERTOIRE_EXPORT + "jurySyntheseDict_" + str(self.diplome) + '_v2.xls'
+        self.xlsV2 = self.table_syntheseJury(mode="multiplesheet")
+        self.zipfile.writestr(filename, self.xlsV2.excel() )
 
     def get_zippeddata(self):
         """returns zipped data with all generated (CSV) files
@@ -400,7 +411,7 @@
                 if lesEtudidsManquants:
                     pe_print(u"   - dont %d étudiants manquants ajoutés aux données du jury" % (len(lesEtudidsManquants)) + ": " + ", ".join(lesEtudidsManquants))
                 pe_print(u"    - Export csv")
-                filename = self.REPERTOIRE_EXPORT + self.semTagDict[fid].nom + '.csv'     
+                filename = self.REPERTOIRE_EXPORT + self.semTagDict[fid].nom + '.csv'
                 self.zipfile.writestr(filename, self.semTagDict[fid].str_tagtable())
     
     # ----------------------------------------------------------------------------------------------------------------
@@ -631,15 +642,25 @@
     
     def get_allTagForAggregat(self, nom_aggregat):
         """Extrait du dictionnaire syntheseJury la liste des tags d'un semestre ou
-         d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie None si aucun tag."""
+         d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie [] si aucun tag."""
         taglist = set()
         for etudid in self.get_etudids_du_jury():
             taglist = taglist.union( set( self.syntheseJury[etudid][nom_aggregat]['groupe'].keys()) )
             taglist = taglist.union( set( self.syntheseJury[etudid][nom_aggregat]['promo'].keys()) )
         return list(taglist)
 
-    def table_syntheseJury(self): # XXX was str_syntheseJury
-        """Table du jury"""
+    def get_allTagInSyntheseJury(self):
+        """Extrait tous les tags du dictionnaire syntheseJury trié par ordre alphabétique. [] si aucun tag """
+        allTags = set()
+        for nom in JuryPE.PARCOURS.keys():
+            allTags = allTags.union( set(self.get_allTagForAggregat(nom)) )
+        return sorted( list(allTags) ) if len(allTags)>0 else []
+
+    def table_syntheseJury(self, mode='singlesheet'): # XXX was str_syntheseJury
+        """Table(s) du jury
+        mode: singlesheet ou multiplesheet pour export excel
+        """
+
         etudids =  self.syntheseJury.keys()
         if not etudids:
             return ''
@@ -648,59 +669,74 @@
         infos = ['sexe', 'nom', 'prenom', 'age', 'nbSemestres' ]
         entete = ['etudid']
         entete.extend( infos )
-        semestres = ['S1', 'S2', 'S3', 'S4']
-        aggregats = ['1A', '2A', '3S', '4S']
+        #semestres = ['S1', 'S2', 'S3', 'S4']
+        #aggregats = ['1A', '2A', '3S', '4S'] -> la somme correspond à PARCOURS.keys()
         #entete.extend( ['Parcours'] + ['']*(maxParcours-1) )
         entete.extend( [ 'P%d' % i for i in range(1,maxParcours+1) ] )
         champs = ['note', 'class groupe', 'class promo' , 'min/moy/max groupe', 'min/moy/max promo']
-        for sem in semestres + aggregats:
-            tags = self.get_allTagForAggregat( sem )
-            entete.extend( ['%s %s %s' % (sem, tag, champ) for tag in tags for champ in champs] )
 
+        if mode == "multiplesheet":
+            allSheets = self.get_allTagInSyntheseJury() # tous les tags de syntheseJuryDict
+            for sem in JuryPE.PARCOURS.keys(): # ['S1', 'S2', ..., '1A', '4S']
+                entete.extend( ['%s %s' % (sem, champ) for champ in champs] )
+        else: # "singlesheet"
+            allSheets = ["singlesheet"]
+            for sem in JuryPE.PARCOURS.keys(): # ['S1', 'S2', ..., '1A', '4S']
+                tags = self.get_allTagForAggregat( sem )
+                entete.extend( ['%s %s %s' % (sem, tag, champ) for tag in tags for champ in champs] )
+
         columns_ids = entete        # les id et les titres de colonnes sont ici identiques
         titles = { i:i for i in columns_ids }
-        
-        rows = []
-        for etudid in etudids:
-            e = self.syntheseJury[etudid]
-            # Les info générales:
-            row = {
-                'etudid' : etudid,
-                'sexe' : e['sexe'],
-                'nom' : e['nom'],
-                'prenom' : e['prenom'],
-                'age' : e['age'],
-                'nbSemestres' : e['nbSemestres']
-                }
-            # Les parcours: P1, P2, ...
-            n = 1
-            for p in e['parcours']:
-                row['P%d' % n] = p
-                n += 1
-            #if self.syntheseJury[etudid]['nbSemestres'] < maxParcours:
-            #    descr += delim.join( ['']*( maxParcours -self.syntheseJury[etudid]['nbSemestres']) ) + delim
-            for sem in semestres + aggregats:
-                for tag in self.get_allTagForAggregat( sem ):
-                    if tag in self.syntheseJury[etudid][sem]['groupe']:
-                        resgroupe = self.syntheseJury[etudid][sem]['groupe'][tag] # tuple
-                    else :
-                        resgroupe = (None, None, None, None, None, None, None)
-                    if tag in self.syntheseJury[etudid][sem]['promo']:
-                        respromo = self.syntheseJury[etudid][sem]['promo'][tag]
-                    else :
-                        respromo = (None, None, None, None, None, None, None)
 
-                    #note = "%2.2f" % resgroupe[0] if isinstance(resgroupe[0], float) else str(resgroupe[0])
-                    row['%s %s %s' % (sem, tag, 'note')] = fmt_note(resgroupe[0])
-                    row['%s %s %s' % (sem, tag, 'class groupe')] = '%s / %s' % (resgroupe[2], resgroupe[3])
-                    row['%s %s %s' % (sem, tag, 'class promo')]  = '%s / %s' % (respromo[2], respromo[3])
-                    row['%s %s %s' % (sem, tag, 'min/moy/max groupe')] = '%s / %s / %s' % tuple( fmt_note(x) for x in (resgroupe[4:7]) )
-                    row['%s %s %s' % (sem, tag, 'min/moy/max promo')] = '%s / %s / %s' % tuple( fmt_note(x) for x in (respromo[4:7]) )
-            rows.append(row)
-            
-        T = GenTable( columns_ids=columns_ids, rows=rows, titles=titles, html_sortable=True )
-        
-        return T
+        sT = SeqGenTable()
+        for sheet in allSheets: # Pour tous les sheets à générer (1 si singlesheet, autant que de tags si multiplesheet)
+            rows = []
+            for etudid in etudids:
+                e = self.syntheseJury[etudid]
+                # Les info générales:
+                row = {
+                    'etudid' : etudid,
+                    'sexe' : e['sexe'],
+                    'nom' : e['nom'],
+                    'prenom' : e['prenom'],
+                    'age' : e['age'],
+                    'nbSemestres' : e['nbSemestres']
+                    }
+                # Les parcours: P1, P2, ...
+                n = 1
+                for p in e['parcours']:
+                    row['P%d' % n] = p
+                    n += 1
+                #if self.syntheseJury[etudid]['nbSemestres'] < maxParcours:
+                #    descr += delim.join( ['']*( maxParcours -self.syntheseJury[etudid]['nbSemestres']) ) + delim
+                for sem in JuryPE.PARCOURS.keys():
+                    listeTags = self.get_allTagForAggregat( sem ) if mode=="singlesheet" else [sheet]
+                    for tag in listeTags :
+                        if tag in self.syntheseJury[etudid][sem]['groupe']:
+                            resgroupe = self.syntheseJury[etudid][sem]['groupe'][tag] # tuple
+                        else :
+                            resgroupe = (None, None, None, None, None, None, None)
+                        if tag in self.syntheseJury[etudid][sem]['promo']:
+                            respromo = self.syntheseJury[etudid][sem]['promo'][tag]
+                        else :
+                            respromo = (None, None, None, None, None, None, None)
+
+                        #note = "%2.2f" % resgroupe[0] if isinstance(resgroupe[0], float) else str(resgroupe[0])
+                        champ = '%s %s ' % (sem, tag) if mode=='singlesheet' else '%s ' % (sem)
+                        row[champ + 'note'] = fmt_note(resgroupe[0])
+                        row[champ + 'class groupe'] = '%s / %s' % (resgroupe[2], resgroupe[3])
+                        row[champ + 'class promo']  = '%s / %s' % (respromo[2], respromo[3])
+                        row[champ + 'min/moy/max groupe'] = '%s / %s / %s' % tuple( fmt_note(x) for x in (resgroupe[4:7]) )
+                        row[champ + 'min/moy/max promo'] = '%s / %s / %s' % tuple( fmt_note(x) for x in (respromo[4:7]) )
+                rows.append(row)
+
+            T = GenTable( columns_ids=columns_ids, rows=rows, titles=titles, html_sortable=True, xls_sheet_name=sheet )
+            sT.add_genTable(sheet, T)
+
+        if mode=="singlesheet":
+            return sT.get_genTable("singlesheet")
+        else:
+            return sT
     
     # **************************************************************************************************************** #
     # Méthodes de classe pour gestion d'un cache de données accélérant les calculs / intérêt à débattre

Modified: branches/ScoDoc7/sco_excel.py
===================================================================
--- branches/ScoDoc7/sco_excel.py	2017-07-01 09:47:56 UTC (rev 1656)
+++ branches/ScoDoc7/sco_excel.py	2017-07-01 10:26:03 UTC (rev 1657)
@@ -190,9 +190,15 @@
                 or self.cells_styles_co.get(co, None) 
                 or self.default_style)
 
-    def gen_workbook(self):
-        """Generates and returns a workbook from stored data"""
-        wb = Workbook()
+    def gen_workbook(self, wb=None):
+        """Generates and returns a workbook from stored data.
+        If wb, add a sheet (tab) to the existing workbook (in this case, returns None).
+        """
+        if wb==None:
+            wb = Workbook() # Création du fichier
+            sauvegarde = True
+        else:
+            sauvegarde = False
         ws0 = wb.add_sheet(self.sheet_name.decode(SCO_ENCODING))
         li = 0
         for l in self.cells:
@@ -207,7 +213,10 @@
                 ws0.write(li, co, c, self.get_cell_style(li,co))
                 co += 1
             li += 1
-        return wb.savetostr()
+        if sauvegarde == True:
+            return wb.savetostr()
+        else:
+            return None
 
 def Excel_SimpleTable( titles=[], lines=[[]],                       
                        SheetName='feuille',


Plus d'informations sur la liste de diffusion scodoc-devel