Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
SCODOC_R6A06
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Paul Milleville
SCODOC_R6A06
Commits
d3672423
Commit
d3672423
authored
6 months ago
by
Emmanuel Viennet
Browse files
Options
Downloads
Patches
Plain Diff
Export excel table recap avec colonnes choisies en HTML
parent
cf780812
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
app/scodoc/sco_recapcomplet.py
+19
-5
19 additions, 5 deletions
app/scodoc/sco_recapcomplet.py
app/static/js/table_recap.js
+28
-0
28 additions, 0 deletions
app/static/js/table_recap.js
app/tables/table_builder.py
+22
-12
22 additions, 12 deletions
app/tables/table_builder.py
with
69 additions
and
17 deletions
app/scodoc/sco_recapcomplet.py
+
19
−
5
View file @
d3672423
...
@@ -63,6 +63,7 @@ def formsemestre_recapcomplet(
...
@@ -63,6 +63,7 @@ def formsemestre_recapcomplet(
xml_with_decisions
=
False
,
xml_with_decisions
=
False
,
force_publishing
=
True
,
force_publishing
=
True
,
selected_etudid
=
None
,
selected_etudid
=
None
,
visible_col_ids
=
None
,
):
):
"""
Page récapitulant les notes d
'
un semestre.
"""
Page récapitulant les notes d
'
un semestre.
Grand tableau récapitulatif avec toutes les notes de modules
Grand tableau récapitulatif avec toutes les notes de modules
...
@@ -86,7 +87,7 @@ def formsemestre_recapcomplet(
...
@@ -86,7 +87,7 @@ def formsemestre_recapcomplet(
if
not
isinstance
(
formsemestre_id
,
int
):
if
not
isinstance
(
formsemestre_id
,
int
):
abort
(
404
)
abort
(
404
)
formsemestre
=
FormSemestre
.
get_formsemestre
(
formsemestre_id
)
formsemestre
=
FormSemestre
.
get_formsemestre
(
formsemestre_id
)
file_formats
=
{
"
csv
"
,
"
json
"
,
"
xls
"
,
"
xlsx
"
,
"
xlsall
"
,
"
xml
"
}
file_formats
=
{
"
csv
"
,
"
json
"
,
"
xls
"
,
"
xlsx
"
,
"
xlsall
"
,
"
xlsvisible
"
,
"
xml
"
}
supported_formats
=
file_formats
|
{
"
html
"
,
"
evals
"
}
supported_formats
=
file_formats
|
{
"
html
"
,
"
evals
"
}
if
tabformat
not
in
supported_formats
:
if
tabformat
not
in
supported_formats
:
raise
ScoValueError
(
f
"
Format non supporté:
{
tabformat
}
"
)
raise
ScoValueError
(
f
"
Format non supporté:
{
tabformat
}
"
)
...
@@ -94,6 +95,7 @@ def formsemestre_recapcomplet(
...
@@ -94,6 +95,7 @@ def formsemestre_recapcomplet(
mode_jury
=
int
(
mode_jury
)
mode_jury
=
int
(
mode_jury
)
xml_with_decisions
=
int
(
xml_with_decisions
)
xml_with_decisions
=
int
(
xml_with_decisions
)
force_publishing
=
int
(
force_publishing
)
force_publishing
=
int
(
force_publishing
)
visible_col_ids
=
visible_col_ids
.
split
(
"
,
"
)
if
visible_col_ids
else
None
filename
=
scu
.
sanitize_filename
(
filename
=
scu
.
sanitize_filename
(
f
"""
{
'
jury
'
if
mode_jury
else
'
recap
'
f
"""
{
'
jury
'
if
mode_jury
else
'
recap
'
}{
'
-evals
'
if
tabformat
==
'
xlsall
'
else
''
}{
'
-evals
'
if
tabformat
==
'
xlsall
'
else
''
...
@@ -107,6 +109,7 @@ def formsemestre_recapcomplet(
...
@@ -107,6 +109,7 @@ def formsemestre_recapcomplet(
filename
=
filename
,
filename
=
filename
,
xml_with_decisions
=
xml_with_decisions
,
xml_with_decisions
=
xml_with_decisions
,
force_publishing
=
force_publishing
,
force_publishing
=
force_publishing
,
visible_col_ids
=
visible_col_ids
,
)
)
table_html
,
_
,
freq_codes_annuels
=
_formsemestre_recapcomplet_to_html
(
table_html
,
_
,
freq_codes_annuels
=
_formsemestre_recapcomplet_to_html
(
...
@@ -124,8 +127,9 @@ def formsemestre_recapcomplet(
...
@@ -124,8 +127,9 @@ def formsemestre_recapcomplet(
]
]
if
len
(
formsemestre
.
inscriptions
)
>
0
:
if
len
(
formsemestre
.
inscriptions
)
>
0
:
H
.
append
(
H
.
append
(
f
"""
<form name=
"
f
"
method=
"
get
"
action=
"
{
request
.
base_url
}
"
>
f
"""
<form
id=
"
export_menu
"
name=
"
f
"
method=
"
get
"
action=
"
{
request
.
base_url
}
"
>
<input type=
"
hidden
"
name=
"
formsemestre_id
"
value=
"
{
formsemestre_id
}
"
></input>
<input type=
"
hidden
"
name=
"
formsemestre_id
"
value=
"
{
formsemestre_id
}
"
></input>
<input type=
"
hidden
"
id=
"
visible_col_ids
"
name=
"
visible_col_ids
"
value=
""
></input>
"""
"""
)
)
if
mode_jury
:
if
mode_jury
:
...
@@ -133,13 +137,14 @@ def formsemestre_recapcomplet(
...
@@ -133,13 +137,14 @@ def formsemestre_recapcomplet(
f
'
<input type=
"
hidden
"
name=
"
mode_jury
"
value=
"
{
mode_jury
}
"
></input>
'
f
'
<input type=
"
hidden
"
name=
"
mode_jury
"
value=
"
{
mode_jury
}
"
></input>
'
)
)
H
.
append
(
H
.
append
(
'
<select name=
"
tabformat
"
onchange=
"
document.f.submit
()
"
class=
"
noprint
"
>
'
'
<select name=
"
tabformat
"
id=
"
tabformat
"
onchange=
"
submit_from_export_menu
()
;
"
class=
"
noprint
"
>
'
)
)
for
fmt
,
label
in
(
for
fmt
,
label
in
(
(
"
html
"
,
"
Tableau
"
),
(
"
html
"
,
"
Tableau
"
),
(
"
evals
"
,
"
Avec toutes les évaluations
"
),
(
"
evals
"
,
"
Avec toutes les évaluations
"
),
(
"
xlsx
"
,
"
Excel (non formaté)
"
),
(
"
xlsx
"
,
"
Excel (non formaté)
"
),
(
"
xlsall
"
,
"
Excel avec évaluations
"
),
(
"
xlsall
"
,
"
Excel avec évaluations
"
),
(
"
xlsvisible
"
,
"
Excel avec colonnes telles affichées
"
),
(
"
json
"
,
"
Bulletins JSON
"
),
(
"
json
"
,
"
Bulletins JSON
"
),
):
):
if
fmt
==
tabformat
:
if
fmt
==
tabformat
:
...
@@ -314,16 +319,19 @@ def _formsemestre_recapcomplet_to_file(
...
@@ -314,16 +319,19 @@ def _formsemestre_recapcomplet_to_file(
xml_nodate
=
False
,
# format XML sans dates (sert pour debug cache: comparaison de XML)
xml_nodate
=
False
,
# format XML sans dates (sert pour debug cache: comparaison de XML)
xml_with_decisions
=
False
,
xml_with_decisions
=
False
,
force_publishing
=
True
,
force_publishing
=
True
,
visible_col_ids
=
None
,
):
):
"""
Calcule et renvoie le tableau récapitulatif.
"""
"""
Calcule et renvoie le tableau récapitulatif.
"""
if
tabformat
.
startswith
(
"
xls
"
):
if
tabformat
.
startswith
(
"
xls
"
):
include_evaluations
=
tabformat
==
"
xlsall
"
include_evaluations
=
tabformat
==
"
xlsall
"
visible_col_ids
=
visible_col_ids
if
tabformat
==
"
xlsvisible
"
else
None
res
:
NotesTableCompat
=
res_sem
.
load_formsemestre_results
(
formsemestre
)
res
:
NotesTableCompat
=
res_sem
.
load_formsemestre_results
(
formsemestre
)
data
,
filename
=
gen_formsemestre_recapcomplet_excel
(
data
,
filename
=
gen_formsemestre_recapcomplet_excel
(
res
,
res
,
mode_jury
=
mode_jury
,
mode_jury
=
mode_jury
,
include_evaluations
=
include_evaluations
,
include_evaluations
=
include_evaluations
,
filename
=
filename
,
filename
=
filename
,
visible_col_ids
=
visible_col_ids
,
)
)
mime
,
suffix
=
scu
.
get_mime_suffix
(
"
xlsx
"
)
mime
,
suffix
=
scu
.
get_mime_suffix
(
"
xlsx
"
)
return
scu
.
send_file
(
data
,
filename
=
filename
,
mime
=
mime
,
suffix
=
suffix
)
return
scu
.
send_file
(
data
,
filename
=
filename
,
mime
=
mime
,
suffix
=
suffix
)
...
@@ -537,11 +545,13 @@ def gen_formsemestre_recapcomplet_excel(
...
@@ -537,11 +545,13 @@ def gen_formsemestre_recapcomplet_excel(
mode_jury
:
bool
=
False
,
mode_jury
:
bool
=
False
,
include_evaluations
=
False
,
include_evaluations
=
False
,
filename
:
str
=
""
,
filename
:
str
=
""
,
visible_col_ids
:
list
[
str
]
|
None
=
None
,
)
->
tuple
:
)
->
tuple
:
"""
Génère le tableau recap ou jury en excel (xlsx).
"""
Génère le tableau recap ou jury en excel (xlsx).
Utilisé pour menu (export excel), archives et autres besoins particuliers (API).
Utilisé pour menu (export excel), archives et autres besoins particuliers (API).
Attention: le tableau exporté depuis la page html est celui généré en js par DataTables,
Attention: le tableau exporté depuis la page html est celui généré en js par DataTables,
et non celui-ci.
et non celui-ci.
Si visible_col_ids est non None, ne génère que les colonnes indiquées (+ les codes étudiants, toujours présents)
"""
"""
# En excel, ajoute les adresses mail, si on a le droit de les voir.
# En excel, ajoute les adresses mail, si on a le droit de les voir.
table
=
_gen_formsemestre_recapcomplet_table
(
table
=
_gen_formsemestre_recapcomplet_table
(
...
@@ -552,5 +562,9 @@ def gen_formsemestre_recapcomplet_excel(
...
@@ -552,5 +562,9 @@ def gen_formsemestre_recapcomplet_excel(
convert_values
=
False
,
convert_values
=
False
,
filename
=
filename
,
filename
=
filename
,
)
)
if
visible_col_ids
is
not
None
:
return
table
.
excel
(),
filename
# Ajoute colonnes qui doivent toujours être présentes en excel:
for
cod
in
(
"
code_nip
"
,
"
etudid
"
):
if
cod
not
in
visible_col_ids
:
visible_col_ids
=
[
cod
]
+
visible_col_ids
return
table
.
excel
(
col_ids
=
visible_col_ids
),
filename
This diff is collapsed.
Click to expand it.
app/static/js/table_recap.js
+
28
−
0
View file @
d3672423
...
@@ -326,3 +326,31 @@ $(function () {
...
@@ -326,3 +326,31 @@ $(function () {
}
}
});
});
});
});
// liste des id de colonnes visibles, dans leur ordre d'affichage
// (chaine avec ids séparés par des virgules)
function
get_visible_column_ids
()
{
const
table
=
$
(
"
table.table_recap
"
).
DataTable
();
const
visibles
=
table
.
columns
().
visible
();
let
col_ids
=
""
;
for
(
i
=
0
;
i
<
visibles
.
length
;
i
++
)
{
if
(
visibles
[
i
])
{
let
th
=
table
.
column
(
i
).
header
();
if
(
col_ids
.
length
)
{
col_ids
+=
"
,
"
;
}
col_ids
+=
th
.
dataset
.
col_id
;
}
}
return
col_ids
;
}
function
submit_from_export_menu
()
{
let
form
=
document
.
querySelector
(
"
#export_menu
"
);
let
tabformat
=
document
.
getElementById
(
"
tabformat
"
).
value
;
if
(
tabformat
==
"
xlsvisible
"
)
{
let
cols_input
=
document
.
getElementById
(
"
visible_col_ids
"
);
cols_input
.
value
=
get_visible_column_ids
();
}
form
.
submit
();
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app/tables/table_builder.py
+
22
−
12
View file @
d3672423
...
@@ -90,8 +90,8 @@ class Table(Element):
...
@@ -90,8 +90,8 @@ class Table(Element):
"
ordered list of column groups names
"
"
ordered list of column groups names
"
self
.
group_titles
=
{}
self
.
group_titles
=
{}
"
title (in header top row) for the group
"
"
title (in header top row) for the group
"
self
.
head
=
[]
self
.
head
:
list
[
"
Row
"
]
=
[]
self
.
foot
=
[]
self
.
foot
:
list
[
"
Row
"
]
=
[]
self
.
column_group
=
{}
self
.
column_group
=
{}
"
the group of the column: { col_id : group }
"
"
the group of the column: { col_id : group }
"
self
.
column_classes
:
defaultdict
[
str
,
set
[
str
]]
=
defaultdict
(
set
)
self
.
column_classes
:
defaultdict
[
str
,
set
[
str
]]
=
defaultdict
(
set
)
...
@@ -281,6 +281,7 @@ class Table(Element):
...
@@ -281,6 +281,7 @@ class Table(Element):
col_id
,
col_id
,
None
,
None
,
title
,
title
,
attrs
=
{
"
data-col_id
"
:
col_id
},
classes
=
classes
,
classes
=
classes
,
group
=
self
.
column_group
.
get
(
col_id
),
group
=
self
.
column_group
.
get
(
col_id
),
raw_content
=
raw_title
or
title
,
raw_content
=
raw_title
or
title
,
...
@@ -297,8 +298,10 @@ class Table(Element):
...
@@ -297,8 +298,10 @@ class Table(Element):
foot_cell
=
self
.
foot_title_row
.
cells
[
col_id
]
if
self
.
foot_title_row
else
None
foot_cell
=
self
.
foot_title_row
.
cells
[
col_id
]
if
self
.
foot_title_row
else
None
return
head_cell
,
foot_cell
return
head_cell
,
foot_cell
def
excel
(
self
,
wb
:
Workbook
=
None
):
def
excel
(
self
,
wb
:
Workbook
=
None
,
col_ids
=
None
):
"""
Simple Excel representation of the table.
"""
"""
Simple Excel representation of the table.
Si col_ids(liste d
'
ids) est spécifié, ne génère que ces colonnes, dans l
'
ordre.
"""
self
.
_prepare
()
self
.
_prepare
()
if
wb
is
None
:
if
wb
is
None
:
sheet
=
sco_excel
.
ScoExcelSheet
(
sheet_name
=
self
.
xls_sheet_name
,
wb
=
wb
)
sheet
=
sco_excel
.
ScoExcelSheet
(
sheet_name
=
self
.
xls_sheet_name
,
wb
=
wb
)
...
@@ -309,13 +312,13 @@ class Table(Element):
...
@@ -309,13 +312,13 @@ class Table(Element):
style_base
=
self
.
xls_style_base
or
sco_excel
.
excel_make_style
()
style_base
=
self
.
xls_style_base
or
sco_excel
.
excel_make_style
()
for
row
in
self
.
head
:
for
row
in
self
.
head
:
sheet
.
append_row
(
row
.
to_excel
(
sheet
,
style
=
style_bold
))
sheet
.
append_row
(
row
.
to_excel
(
sheet
,
style
=
style_bold
,
col_ids
=
col_ids
))
for
row
in
self
.
rows
:
for
row
in
self
.
rows
:
sheet
.
append_row
(
row
.
to_excel
(
sheet
,
style
=
style_base
))
sheet
.
append_row
(
row
.
to_excel
(
sheet
,
style
=
style_base
,
col_ids
=
col_ids
))
for
row
in
self
.
foot
:
for
row
in
self
.
foot
:
sheet
.
append_row
(
row
.
to_excel
(
sheet
,
style
=
style_base
))
sheet
.
append_row
(
row
.
to_excel
(
sheet
,
style
=
style_base
,
col_ids
=
col_ids
))
if
self
.
caption
:
if
self
.
caption
:
sheet
.
append_blank_row
()
# empty line
sheet
.
append_blank_row
()
# empty line
...
@@ -325,9 +328,10 @@ class Table(Element):
...
@@ -325,9 +328,10 @@ class Table(Element):
sheet
.
append_single_cell_row
(
self
.
origin
,
style_base
)
sheet
.
append_single_cell_row
(
self
.
origin
,
style_base
)
# Largeurs des colonnes
# Largeurs des colonnes
actual_col_ids
=
col_ids
if
col_ids
else
self
.
column_ids
for
col_id
,
width
in
self
.
xls_columns_width
.
items
():
for
col_id
,
width
in
self
.
xls_columns_width
.
items
():
try
:
try
:
idx
=
self
.
column
_ids
.
index
(
col_id
)
idx
=
actual_col
_ids
.
index
(
col_id
)
col
=
get_column_letter
(
idx
+
1
)
col
=
get_column_letter
(
idx
+
1
)
sheet
.
set_column_dimension_width
(
col
,
width
)
sheet
.
set_column_dimension_width
(
col
,
width
)
except
ValueError
:
except
ValueError
:
...
@@ -365,7 +369,7 @@ class Row(Element):
...
@@ -365,7 +369,7 @@ class Row(Element):
title
:
str
,
title
:
str
,
content
:
str
,
content
:
str
,
group
:
str
=
None
,
group
:
str
=
None
,
attrs
:
list
[
str
]
=
None
,
attrs
:
dict
[
str
,
str
]
=
None
,
classes
:
list
[
str
]
=
None
,
classes
:
list
[
str
]
=
None
,
data
:
dict
[
str
,
str
]
=
None
,
data
:
dict
[
str
,
str
]
=
None
,
elt
:
str
=
None
,
elt
:
str
=
None
,
...
@@ -466,9 +470,15 @@ class Row(Element):
...
@@ -466,9 +470,15 @@ class Row(Element):
for
col_id
in
self
.
table
.
raw_column_ids
for
col_id
in
self
.
table
.
raw_column_ids
}
}
def
to_excel
(
self
,
sheet
,
style
=
None
)
->
list
:
def
to_excel
(
self
,
sheet
,
style
=
None
,
col_ids
=
None
)
->
list
:
"
build excel row for given sheet
"
"""
Build excel row for given sheet.
If col_ids is given, generate only this columns
"""
if
col_ids
is
None
:
return
sheet
.
make_row
(
self
.
to_dict
().
values
(),
style
=
style
)
return
sheet
.
make_row
(
self
.
to_dict
().
values
(),
style
=
style
)
# Version avec seulement colonnes spécifiées:
d
=
self
.
to_dict
()
return
sheet
.
make_row
([
d
[
k
]
for
k
in
col_ids
if
k
in
d
],
style
=
style
)
class
BottomRow
(
Row
):
class
BottomRow
(
Row
):
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment