diff --git a/app/comp/res_common.py b/app/comp/res_common.py
index afb7acd00..902d24050 100644
--- a/app/comp/res_common.py
+++ b/app/comp/res_common.py
@@ -760,6 +760,20 @@ class ResultatsSemestre(ResultatsCache):
                 for row in bottom_infos.values():
                     row[c_class] = row.get(c_class, "") + " col_empty"
 
+        # Ligne avec la classe de chaque colonne
+        # récupère le type à partir des classes css (hack...)
+        row_class = {}
+        for col_id in titles:
+            klass = titles.get(f"_{col_id}_class")
+            if klass:
+                row_class[col_id] = " ".join(
+                    cls[4:] for cls in klass.split() if cls.startswith("col_")
+                )
+                # cette case (nb d'UE validables) a deux classes col_xxx, on en garde une seule:
+                if "ues_validables" in row_class[col_id]:
+                    row_class[col_id] = "ues_validables"
+        bottom_infos["type_col"] = row_class
+
         # --- TABLE FOOTER: ECTS, moyennes, min, max...
         footer_rows = []
         for (bottom_line, row) in bottom_infos.items():
@@ -783,7 +797,7 @@ class ResultatsSemestre(ResultatsCache):
         return (rows, footer_rows, titles, column_ids)
 
     def _recap_bottom_infos(self, ues, modimpl_ids: set, fmt_note) -> dict:
-        """Les informations à mettre en bas de la table: min, max, moy, ECTS"""
+        """Les informations à mettre en bas de la table: min, max, moy, ECTS, Apo"""
         row_min, row_max, row_moy, row_coef, row_ects, row_apo = (
             {"_tr_class": "bottom_info", "_title": "Min."},
             {"_tr_class": "bottom_info"},
@@ -843,7 +857,7 @@ class ResultatsSemestre(ResultatsCache):
                         row_moy[f"_{colid}_class"] = "col_empty"
                     row_apo[colid] = modimpl.module.code_apogee or ""
 
-        return {  # { key : row } avec key = min, max, moy, coef
+        return {  # { key : row } avec key = min, max, moy, coef, ...
             "min": row_min,
             "max": row_max,
             "moy": row_moy,
diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css
index 9e73cd947..254defd54 100644
--- a/app/static/css/scodoc.css
+++ b/app/static/css/scodoc.css
@@ -4199,6 +4199,11 @@ table.table_recap tr.apo td {
   background-color: #d8f5fe;
 }
 
+table.table_recap tr.type_col {
+  font-size: 50%;
+  font-family: monospace;
+}
+
 table.table_recap td.evaluation.first,
 table.table_recap th.evaluation.first {
   border-left: 2px solid rgb(4, 16, 159);
diff --git a/app/static/js/table_recap.js b/app/static/js/table_recap.js
index 11b29c6a0..9352e25c9 100644
--- a/app/static/js/table_recap.js
+++ b/app/static/js/table_recap.js
@@ -201,6 +201,7 @@ $(function () {
                     },
                     {
                         extend: 'excelHtml5',
+                        // footer: true, // ne fonctionne pas ?
                         exportOptions: { orthogonal: 'export' },
                         title: document.querySelector('table.table_recap').dataset.filename
                     },