Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Développeurs

Mise en forme des exports Excel (XLSX)

Mise en forme automatique des exports Excel des rapports et fonction get_xlsx_styles pour définir un style propre à un rapport standard.

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émentStyle
Ligne d'en-têtesGras. 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 arborescentRetrait de la première colonne selon la valeur indent de la ligne
Colonnes Float et PercentFormat numérique avec le séparateur de milliers et la précision du système
Colonnes Date, Time et DatetimeFormat de date ou d'heure du système, aligné à droite
Colonnes CurrencyFormat 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éthodeContenu
column_mapIndex de colonne vers la définition de la colonne (fieldname, fieldtype, options…)
row_mapIndex de ligne vers les données de la ligne (dictionnaire ou liste)
applied_filters_mapIndex de ligne vers le couple libellé et valeur d'un filtre
has_total_row, has_indentationPrésence d'une ligne de total, d'un retrait
report_name, filtersNom 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éthodeEffet
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
resultDictionnaire à 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.