# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2019 Emmanuel Viennet. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Emmanuel Viennet emmanuel.viennet@viennet.net # ############################################################################## """ Excel file formatting """ # from sco_excel_add import * import copy from enum import IntFlag, Enum from app.scodoc.sco_excel import excel_make_style from app.scodoc.sco_excel_add import make_font, make_pattern, make_numfmt, make_borders class CellBorder(IntFlag): TOP = 1 << 0 BOTTOM = 1 << 1 LEFT = 1 << 2 RIGHT = 1 << 3 # Liste des modificateurs de format class CellFormat(IntFlag): # Mise en Forme usuelle FMT_CAP_UE = 1 << 4 # UE capitalisée FMT_MOY = 1 << 5 # Moyenne de semestre FMT_UE = 1 << 6 # Acquisition d'UE sans validation semestre # Mise en Forme sur le contenu EMPHASE_PREC = 1 << 7 # Cause échec de semestre EMPHASE_ATB = 1 << 8 # Cause échec de semestre EMPHASE_UEACQ = 1 << 9 # Cause échec de semestre EMPHASE_ATT = 1 << 10 # Cause échec de semestre EMPHASE_ABS = 1 << 11 # Absences EMPHASE_COMP = 1 << 12 # Cause échec de semestre # Mise en forme numérique PRECISE = 1 << 20 # Précision de l'affichage GRAYED = 1 << 22 # Grisé horizontal # Color palette at : https://groups.google.com/g/python-excel/c/cePI-ojUJfc/m/dH72A-rm6_gJ class CellColor(Enum): COLOR_PREC = "D2B48C" # TAN COLOR_ATB = "93CCEA" # LIGHT CORNFLOWER BLUE COLOR_ATT = "FE8DB1" # LIGHT ORANGE COLOR_COMP = "90EE90" # LIGHT GREEN COLOR_UEACQ = "90EE90" # LIGHT GREEN COLOR_ABS = "44845E" # LIGHT YELLOW def format_note(valeur, warning, seuil, mini=True): if seuil is not None: if isinstance(valeur, (int, float)): if mini: diff = valeur - seuil else: diff = seuil - valeur if -0.20 < diff < 0: warning += CellFormat.PRECISE return warning class Formatter: def __init__(self): self.style_table = {} self.last_rank = None self.left_borders = [] self.right_borders = [] self.default_top = "none" self.default_bottom = "none" self.default_left = "none" self.default_right = "none" self.default_format = None # def add_category(self, left, right): # self.left_borders.append(left) # self.right_borders.append(right) def set_borders_default(self, left="none", top="none", bottom="none", right="none"): self.default_bottom = bottom self.default_left = left self.default_right = right self.default_top = top def borders(self, li, co): index = 0 index |= CellBorder.TOP if li == 0 else 0 index |= CellBorder.BOTTOM if self.last_rank and li == self.last_rank else 0 index |= CellBorder.LEFT if co in self.left_borders else 0 index |= CellBorder.RIGHT if co in self.right_borders else 0 return index def get_style(self, index=0): if index not in self.style_table: border_enable = "filet" if self.default_format: style = copy.copy(self.default_format) else: style = excel_make_style() make_font( style=style, font_name="Calibri", font_size=9, bold=(CellFormat.FMT_MOY & index), uline=(CellFormat.FMT_CAP_UE & index), ) make_borders( style=style, left="none", right="none", top="filet", bottom="filet" ) if index & CellFormat.EMPHASE_ATB: make_pattern(style=style, bgcolor=CellColor.COLOR_ATB.value) elif index & CellFormat.EMPHASE_ATT: make_pattern(style=style, bgcolor=CellColor.COLOR_ATT.value) elif index & CellFormat.EMPHASE_PREC: make_pattern(style=style, bgcolor=CellColor.COLOR_PREC.value) elif index & CellFormat.EMPHASE_COMP: make_pattern(style=style, bgcolor=CellColor.COLOR_COMP.value) elif index & CellFormat.EMPHASE_UEACQ: make_pattern(style=style, bgcolor=CellColor.COLOR_UEACQ.value) elif index & CellFormat.EMPHASE_ABS: make_pattern(style=style, bgcolor=CellColor.COLOR_ABS.value) # elif not index & GRAYED: # make_pattern(style=style, bgcolor=0x43) if index & (CellFormat.FMT_CAP_UE | CellFormat.FMT_UE | CellFormat.FMT_MOY): if index & CellFormat.PRECISE: make_numfmt("#0.00", style) else: make_numfmt("#0.0", style) top = border_enable if index & CellBorder.TOP else self.default_top bottom = border_enable if index & CellBorder.BOTTOM else self.default_bottom left = border_enable if index & CellBorder.LEFT else self.default_left right = border_enable if index & CellBorder.RIGHT else self.default_right make_borders(style=style, top=top, left=left, right=right, bottom=bottom) self.style_table[index] = style return self.style_table[index] def width(self, item): if item is None: return 1 else: compte = 0 for subitem in item.values(): compte += self.width(subitem) return compte def set_default_format(self, default_format): self.default_format = default_format