Mise en forme des exports Excel (XLSX)
Mise en forme des exports Excel (XLSX)
Quand un utilisateur exporte un rapport au format Excel, Dodock écrit le fichier avec la bibliothèque xlsxwriter et applique une mise en forme par défaut. Un rapport standard peut remplacer cette mise en forme avec une fonction get_xlsx_styles dans son fichier Python.
Mise en forme par défaut
| Élément | Style |
|---|---|
| Ligne d'en-têtes | Gras. Alignement à droite pour les colonnes numériques et de date, à gauche pour les autres |
| Lignes de filtres (si l'utilisateur les inclut) | Libellé du filtre en gras |
| Ligne de total (si le rapport en a une) | Gras |
| Rapport arborescent | Retrait de la première colonne selon la valeur indent de la ligne |
| Colonnes Float et Percent | Format numérique avec le séparateur de milliers et la précision du système |
| Colonnes Date, Time et Datetime | Format de date ou d'heure du système, aligné à droite |
| Colonnes Currency | Format monétaire avec le symbole de la devise de la ligne, ou de la devise par défaut |
Le symbole monétaire n'apparaît pas si l'option « masquer le symbole monétaire » est active dans les paramètres par défaut.
Définir un style propre à un rapport
La fonction get_xlsx_styles s'applique seulement aux rapports standard (champ Est un formulaire standard à « Oui ») de type Query Report ou Script Report. Placez-la dans le fichier Python du rapport, à côté de execute.
def get_xlsx_styles(metadata):
...
La fonction reçoit un objet XLSXMetadata et renvoie un dictionnaire de styles. Si elle renvoie None ou un dictionnaire vide, Dodock applique la mise en forme par défaut.
L'objet XLSXMetadata
Tous les index commencent à 0 et comptent toutes les lignes de la feuille (filtres, en-têtes, données).
| Attribut ou méthode | Contenu |
|---|---|
column_map | Index de colonne vers la définition de la colonne (fieldname, fieldtype, options…) |
row_map | Index de ligne vers les données de la ligne (dictionnaire ou liste) |
applied_filters_map | Index de ligne vers le couple libellé et valeur d'un filtre |
has_total_row, has_indentation | Présence d'une ligne de total, d'un retrait |
report_name, filters | Nom du rapport et valeurs des filtres |
get_column(fieldname) | Définition d'une colonne |
get_header_index() | Index de la ligne d'en-têtes |
get_first_row_index(), get_last_row_index() | Index de la première et de la dernière ligne de données |
Construire les styles avec XLSXStyleBuilder
XLSXStyleBuilder(metadata) part de la mise en forme par défaut. Avec default_styling=False, il part d'une feuille sans style.
| Méthode | Effet |
|---|---|
register_style(style) | Enregistre un format xlsxwriter ({"bold": True}, {"bg_color": "#FDE68A"}…) et renvoie son identifiant |
style_column(col_idx, style_id) | Applique le style à une colonne |
style_row(row_idx, style_id) | Applique le style à une ligne |
style_cell(row_idx, col_idx, style_id) | Applique le style à une cellule |
result | Dictionnaire à renvoyer : styles, column_styles, row_styles, cell_styles |
Les propriétés de style sont celles des formats xlsxwriter.
Exemple
Exemple fictif : un rapport Script de soldes clients colore en rouge les soldes négatifs.
# mon_app/mon_module/report/soldes_clients/soldes_clients.py
from frappe.utils.xlsxutils import XLSXStyleBuilder
def execute(filters=None):
columns = [
{"fieldname": "customer", "label": "Client", "fieldtype": "Link", "options": "Customer"},
{"fieldname": "balance", "label": "Solde", "fieldtype": "Currency"},
]
data = [
{"customer": "Menuiserie Élégante", "balance": 1200},
{"customer": "Atelier Durand", "balance": -350},
]
return columns, data
def get_xlsx_styles(metadata):
builder = XLSXStyleBuilder(metadata)
rouge = builder.register_style({"font_color": "#B91C1C"})
col = next(i for i, c in metadata.column_map.items() if c.get("fieldname") == "balance")
for row_idx, row in metadata.row_map.items():
if isinstance(row, dict) and (row.get("balance") or 0) < 0:
builder.style_cell(row_idx, col, rouge)
return builder.result
Dans le fichier exporté, la cellule du solde d'Atelier Durand est en rouge. Les autres styles par défaut restent appliqués.
Fonctions utilitaires
Fonction (frappe.utils.xlsxutils) | Usage |
|---|---|
make_xlsx(data, sheet_name, wb=None, column_widths=None, styles=None) | Crée un fichier XLSX à partir d'une liste de lignes et renvoie un BytesIO |
get_default_xlsx_styles(columns, data, applied_filters=None, *, has_total_row=False, has_indentation=False, currency_formatting=True) | Calcule la mise en forme par défaut pour un export que vous construisez vous-même |
build_xlsx_response(data, filename, styles=None) | Renvoie le fichier XLSX comme réponse de téléchargement |
Si vous passez votre propre classeur à make_xlsx (wb), fermez-le vous-même. Pour un gros volume, créez-le avec l'option constant_memory de xlsxwriter.