forked from ScoDoc/ScoDoc
formattage terminé ?
This commit is contained in:
parent
cfe74da499
commit
342bff3b56
@ -1,26 +1,36 @@
|
|||||||
from enum import Enum
|
from app.but.prepajury_xl import (
|
||||||
from app.but.prepajury_xl import ScoExcelSheet, excel_make_style
|
ScoExcelSheet,
|
||||||
|
)
|
||||||
|
from app.but.prepajury_xl_format import (
|
||||||
|
SCO_HALIGN,
|
||||||
|
SCO_VALIGN,
|
||||||
|
SCO_FONTNAME,
|
||||||
|
SCO_FONTSIZE,
|
||||||
|
FMT,
|
||||||
|
Sco_Style,
|
||||||
|
)
|
||||||
|
|
||||||
base_style = excel_make_style()
|
base_signature = (
|
||||||
|
FMT.FONT_NAME.write(SCO_FONTNAME.FONTNAME_CALIBRI)
|
||||||
|
+ FMT.FONT_SIZE.write(SCO_FONTSIZE.FONTSIZE_10)
|
||||||
|
+ FMT.ALIGNMENT_HALIGN.write(SCO_HALIGN.HALIGN_CENTER)
|
||||||
|
+ FMT.ALIGNEMENT_VALIGN.write(SCO_VALIGN.VALIGN_CENTER)
|
||||||
|
)
|
||||||
|
|
||||||
class BG(Enum):
|
|
||||||
|
|
||||||
NONE = 0,
|
|
||||||
BLACK = 1,
|
|
||||||
GREY = 2,
|
|
||||||
BUT1
|
|
||||||
|
|
||||||
class Cell:
|
class Cell:
|
||||||
def __init__(self, text: str = None, style: int = None, comment: str = None):
|
def __init__(
|
||||||
|
self, text: str = None, signature: int = base_signature, comment: str = None
|
||||||
|
):
|
||||||
self.text = text
|
self.text = text
|
||||||
self.style = style or base_style
|
self.signature = signature or base_signature
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
|
|
||||||
@staticmethod
|
def format(self, FMT: FMT, value=None):
|
||||||
def get_style():
|
self.signature = FMT.composante.write(self.signature, value)
|
||||||
return base_style
|
|
||||||
|
|
||||||
def make_cell(self, worksheet: ScoExcelSheet):
|
def make_cell(self, worksheet: ScoExcelSheet):
|
||||||
style = self.get_style()
|
cell = worksheet.make_cell(self.text or "")
|
||||||
cell = worksheet.make_cell(self.text or "", style=style)
|
style: Sco_Style = FMT.ALL.get_style(self.signature)
|
||||||
|
style.apply(cell)
|
||||||
return cell
|
return cell
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
from openpyxl.styles.colors import BLACK
|
||||||
|
|
||||||
from app.but.prepajury_cells import Cell, base_style
|
from app.but.prepajury_cells import Cell, base_style
|
||||||
from app.but.prepajury_xl import excel_make_style
|
from app.but.prepajury_xl import Sco_Style
|
||||||
|
from app.but.prepajury_xl_format import SCO_COLORS
|
||||||
from app.models import ApcCompetence, ApcParcours
|
from app.models import ApcCompetence, ApcParcours
|
||||||
from app.scodoc.sco_excel import ScoExcelBook, ScoExcelSheet
|
from app.scodoc.sco_excel import ScoExcelBook, ScoExcelSheet
|
||||||
|
|
||||||
@ -9,6 +12,23 @@ def parite(semestre_idx):
|
|||||||
|
|
||||||
|
|
||||||
listeAnnees = ["BUT1", "BUT2", "BUT3"]
|
listeAnnees = ["BUT1", "BUT2", "BUT3"]
|
||||||
|
header_colors = {
|
||||||
|
"BUT1": {
|
||||||
|
"BUT": SCO_COLORS.BUT1,
|
||||||
|
"RCUE": SCO_COLORS.RCUE1,
|
||||||
|
"UE": SCO_COLORS.UE1,
|
||||||
|
},
|
||||||
|
"BUT2": {
|
||||||
|
"BUT": SCO_COLORS.BUT2,
|
||||||
|
"RCUE": SCO_COLORS.RCUE2,
|
||||||
|
"UE": SCO_COLORS.UE2,
|
||||||
|
},
|
||||||
|
"BUT3": {
|
||||||
|
"BUT": SCO_COLORS.BUT3,
|
||||||
|
"RCUE": SCO_COLORS.RCUE3,
|
||||||
|
"UE": SCO_COLORS.UE3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class _Header:
|
class _Header:
|
||||||
@ -20,7 +40,7 @@ class _Header:
|
|||||||
def setLabelOnce(self, rang: int, label: str):
|
def setLabelOnce(self, rang: int, label: str):
|
||||||
self.presets[rang] = label
|
self.presets[rang] = label
|
||||||
|
|
||||||
def setStyles(self, rangs: list[int], style):
|
def setStyles(self, rangs: list[int], style: Sco_Style):
|
||||||
for rang in rangs:
|
for rang in rangs:
|
||||||
self.styles[rang] = style
|
self.styles[rang] = style
|
||||||
|
|
||||||
@ -71,10 +91,16 @@ class NiveauDesc:
|
|||||||
self.ue[parite(scodocUe.semestre_idx)] = scodocUe
|
self.ue[parite(scodocUe.semestre_idx)] = scodocUe
|
||||||
|
|
||||||
def generate_header(self, header):
|
def generate_header(self, header):
|
||||||
|
rcue_style = Sco_Style(
|
||||||
|
fromStyle=base_style,
|
||||||
|
bgcolor=header_colors[self.fromScodoc.annee]["RCUE"],
|
||||||
|
)
|
||||||
|
ue_style = Sco_Style(
|
||||||
|
fromStyle=base_style,
|
||||||
|
bgcolor=header_colors[self.fromScodoc.annee]["UE"],
|
||||||
|
)
|
||||||
header.setLabelOnce(1, self.fromScodoc.competence.titre)
|
header.setLabelOnce(1, self.fromScodoc.competence.titre)
|
||||||
rcue_style = excel_make_style(base_style)
|
header.setStyles([1], rcue_style)
|
||||||
ue_style = excel_make_style(base_style)
|
|
||||||
header.setStyles([1, 2, 3], rcue_style)
|
|
||||||
header.setStyles([2, 3], ue_style)
|
header.setStyles([2, 3], ue_style)
|
||||||
for ue in self.ue:
|
for ue in self.ue:
|
||||||
if ue is None:
|
if ue is None:
|
||||||
@ -135,7 +161,9 @@ class AnneeDesc:
|
|||||||
header.add_column()
|
header.add_column()
|
||||||
|
|
||||||
def generate_header(self, header):
|
def generate_header(self, header):
|
||||||
but_style = excel_make_style(base_style)
|
but_style = Sco_Style(
|
||||||
|
fromStyle=base_style, bgcolor=header_colors[self.codeAnnee]["BUT"]
|
||||||
|
)
|
||||||
header.setStyles([0], but_style)
|
header.setStyles([0], but_style)
|
||||||
for niveau in self.niveaux.values():
|
for niveau in self.niveaux.values():
|
||||||
niveau.generate_header(header)
|
niveau.generate_header(header)
|
||||||
|
@ -25,38 +25,25 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from openpyxl.cell import WriteOnlyCell
|
||||||
|
|
||||||
|
from app.but.prepajury_xl_format import Sco_Style
|
||||||
|
|
||||||
""" Excel file handling
|
""" Excel file handling
|
||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
import io
|
|
||||||
import time
|
|
||||||
from enum import Enum
|
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
import openpyxl.utils.datetime
|
import openpyxl.utils.datetime
|
||||||
from openpyxl.styles.numbers import FORMAT_NUMBER_00, FORMAT_GENERAL, FORMAT_DATE_DDMMYY
|
from openpyxl.styles.numbers import FORMAT_DATE_DDMMYY
|
||||||
from openpyxl.comments import Comment
|
from openpyxl.comments import Comment
|
||||||
from openpyxl import Workbook, load_workbook
|
from openpyxl import Workbook
|
||||||
from openpyxl.cell import WriteOnlyCell
|
|
||||||
from openpyxl.styles import Font, Border, Side, Alignment, PatternFill
|
|
||||||
from openpyxl.worksheet.worksheet import Worksheet
|
|
||||||
|
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app import log
|
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc import notesdb, sco_preferences
|
|
||||||
|
|
||||||
|
|
||||||
class COLORS(Enum):
|
|
||||||
BLACK = "FF000000"
|
|
||||||
WHITE = "FFFFFFFF"
|
|
||||||
RED = "FFFF0000"
|
|
||||||
BROWN = "FF993300"
|
|
||||||
PURPLE = "FF993366"
|
|
||||||
BLUE = "FF0000FF"
|
|
||||||
ORANGE = "FFFF3300"
|
|
||||||
LIGHT_YELLOW = "FFFFFF99"
|
|
||||||
|
|
||||||
|
|
||||||
# Un style est enregistré comme un dictionnaire qui précise la valeur d'un attribut dans la liste suivante:
|
# Un style est enregistré comme un dictionnaire qui précise la valeur d'un attribut dans la liste suivante:
|
||||||
@ -127,67 +114,6 @@ class ScoExcelBook:
|
|||||||
return tmp.read()
|
return tmp.read()
|
||||||
|
|
||||||
|
|
||||||
def excel_make_style(
|
|
||||||
fromStyle=None,
|
|
||||||
bold=False,
|
|
||||||
italic=False,
|
|
||||||
outline=False,
|
|
||||||
color: COLORS = COLORS.BLACK,
|
|
||||||
bgcolor: COLORS = None,
|
|
||||||
halign=None,
|
|
||||||
valign=None,
|
|
||||||
number_format=None,
|
|
||||||
font_name="Arial",
|
|
||||||
size=10,
|
|
||||||
):
|
|
||||||
"""Contruit un style.
|
|
||||||
Les couleurs peuvent être spécfiées soit par une valeur de COLORS,
|
|
||||||
soit par une chaine argb (exple "FF00FF00" pour le vert)
|
|
||||||
color -- La couleur du texte
|
|
||||||
bgcolor -- la couleur de fond
|
|
||||||
halign -- alignement horizontal ("left", "right", "center")
|
|
||||||
valign -- alignement vertical ("top", "bottom", "center")
|
|
||||||
number_format -- formattage du contenu ("General", "@", ...)
|
|
||||||
font_name -- police
|
|
||||||
size -- taille de police
|
|
||||||
"""
|
|
||||||
style = {}
|
|
||||||
if fromStyle is not None:
|
|
||||||
for item in fromStyle:
|
|
||||||
style[item] = fromStyle[item]
|
|
||||||
font = Font(
|
|
||||||
name=font_name,
|
|
||||||
bold=bold,
|
|
||||||
italic=italic,
|
|
||||||
outline=outline,
|
|
||||||
color=color.value,
|
|
||||||
size=size,
|
|
||||||
)
|
|
||||||
style["font"] = font
|
|
||||||
if bgcolor:
|
|
||||||
style["fill"] = PatternFill(fill_type="solid", fgColor=bgcolor.value)
|
|
||||||
if halign or valign:
|
|
||||||
al = Alignment()
|
|
||||||
if halign:
|
|
||||||
al.horizontal = {
|
|
||||||
"left": "left",
|
|
||||||
"right": "right",
|
|
||||||
"center": "center",
|
|
||||||
}[halign]
|
|
||||||
if valign:
|
|
||||||
al.vertical = {
|
|
||||||
"top": "top",
|
|
||||||
"bottom": "bottom",
|
|
||||||
"center": "center",
|
|
||||||
}[valign]
|
|
||||||
style["alignment"] = al
|
|
||||||
if number_format is None:
|
|
||||||
style["number_format"] = FORMAT_GENERAL
|
|
||||||
else:
|
|
||||||
style["number_format"] = number_format
|
|
||||||
return style
|
|
||||||
|
|
||||||
|
|
||||||
class ScoExcelSheet:
|
class ScoExcelSheet:
|
||||||
"""Représente une feuille qui peut être indépendante ou intégrée dans un ScoExcelBook.
|
"""Représente une feuille qui peut être indépendante ou intégrée dans un ScoExcelBook.
|
||||||
En application des directives de la bibliothèque sur l'écriture optimisée, l'ordre des opérations
|
En application des directives de la bibliothèque sur l'écriture optimisée, l'ordre des opérations
|
||||||
@ -208,9 +134,7 @@ class ScoExcelSheet:
|
|||||||
# Le nom de la feuille ne peut faire plus de 31 caractères.
|
# Le nom de la feuille ne peut faire plus de 31 caractères.
|
||||||
# si la taille du nom de feuille est > 31 on tronque (on pourrait remplacer par 'feuille' ?)
|
# si la taille du nom de feuille est > 31 on tronque (on pourrait remplacer par 'feuille' ?)
|
||||||
self.sheet_name = adjust_sheetname(sheet_name)
|
self.sheet_name = adjust_sheetname(sheet_name)
|
||||||
if default_style is None:
|
self.default_style = default_style or Sco_Style()
|
||||||
default_style = excel_make_style()
|
|
||||||
self.default_style = default_style
|
|
||||||
if wb is None:
|
if wb is None:
|
||||||
self.wb = Workbook()
|
self.wb = Workbook()
|
||||||
self.ws = self.wb.active
|
self.ws = self.wb.active
|
||||||
@ -223,29 +147,6 @@ class ScoExcelSheet:
|
|||||||
self.column_dimensions = {}
|
self.column_dimensions = {}
|
||||||
self.row_dimensions = {}
|
self.row_dimensions = {}
|
||||||
|
|
||||||
def excel_make_composite_style(
|
|
||||||
self,
|
|
||||||
alignment=None,
|
|
||||||
border=None,
|
|
||||||
fill=None,
|
|
||||||
number_format=None,
|
|
||||||
font=None,
|
|
||||||
):
|
|
||||||
style = {}
|
|
||||||
if font is not None:
|
|
||||||
style["font"] = font
|
|
||||||
if alignment is not None:
|
|
||||||
style["alignment"] = alignment
|
|
||||||
if border is not None:
|
|
||||||
style["border"] = border
|
|
||||||
if fill is not None:
|
|
||||||
style["fill"] = fill
|
|
||||||
if number_format is None:
|
|
||||||
style["number_format"] = FORMAT_GENERAL
|
|
||||||
else:
|
|
||||||
style["number_format"] = number_format
|
|
||||||
return style
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def i2col(idx):
|
def i2col(idx):
|
||||||
if idx < 26: # one letter key
|
if idx < 26: # one letter key
|
||||||
@ -287,7 +188,7 @@ class ScoExcelSheet:
|
|||||||
"""
|
"""
|
||||||
self.ws.row_dimensions[cle].hidden = value
|
self.ws.row_dimensions[cle].hidden = value
|
||||||
|
|
||||||
def make_cell(self, value: any = None, style=None, comment=None):
|
def make_cell(self, value: any = None, style: Sco_Style = None, comment=None):
|
||||||
"""Construit une cellule.
|
"""Construit une cellule.
|
||||||
value -- contenu de la cellule (texte, numérique, booléen ou date)
|
value -- contenu de la cellule (texte, numérique, booléen ou date)
|
||||||
style -- style par défaut (dictionnaire cf. excel_make_style) de la feuille si non spécifié
|
style -- style par défaut (dictionnaire cf. excel_make_style) de la feuille si non spécifié
|
||||||
@ -313,17 +214,15 @@ class ScoExcelSheet:
|
|||||||
if "font" in style:
|
if "font" in style:
|
||||||
cell.font = style["font"]
|
cell.font = style["font"]
|
||||||
if "alignment" in style:
|
if "alignment" in style:
|
||||||
cell.alignment = style["alignment"]
|
cell.alignment = style["alignment"].get_openxl()
|
||||||
if "border" in style:
|
if "border" in style:
|
||||||
cell.border = style["border"]
|
cell.border = style["border"].get_openxl()
|
||||||
if "fill" in style:
|
|
||||||
cell.fill = style["fill"]
|
|
||||||
if "number_format" in style:
|
if "number_format" in style:
|
||||||
cell.number_format = style["number_format"]
|
cell.number_format = style["number_format"]
|
||||||
if "fill" in style:
|
if "fill" in style:
|
||||||
cell.fill = style["fill"]
|
cell.fill = style["fill"]
|
||||||
if "alignment" in style:
|
if "alignment" in style:
|
||||||
cell.alignment = style["alignment"]
|
cell.alignment = style["alignment"].get_openxl()
|
||||||
if not comment is None:
|
if not comment is None:
|
||||||
cell.comment = Comment(comment, "scodoc")
|
cell.comment = Comment(comment, "scodoc")
|
||||||
lines = comment.splitlines()
|
lines = comment.splitlines()
|
||||||
|
476
app/but/prepajury_xl_format.py
Normal file
476
app/but/prepajury_xl_format.py
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
import abc
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
import openpyxl.styles
|
||||||
|
from openpyxl.styles import Side, Border, Font, PatternFill
|
||||||
|
from openpyxl.styles.numbers import FORMAT_GENERAL, FORMAT_NUMBER_00
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_COLORS(Enum):
|
||||||
|
def __new__(cls, value, argb):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.argb = argb
|
||||||
|
return obj
|
||||||
|
|
||||||
|
BLACK = (1, "FF000000")
|
||||||
|
WHITE = (2, "FFFFFFFF")
|
||||||
|
RED = (3, "FFFF0000")
|
||||||
|
BROWN = (4, "FF993300")
|
||||||
|
PURPLE = (5, "FF993366")
|
||||||
|
BLUE = (6, "FF0000FF")
|
||||||
|
ORANGE = (7, "FFFF3300")
|
||||||
|
LIGHT_YELLOW = (8, "FFFFFF99")
|
||||||
|
BUT1 = (9, "FF95B3D7")
|
||||||
|
RCUE1 = (10, "FFB8CCE4")
|
||||||
|
UE1 = (11, "FFDCE6F1")
|
||||||
|
BUT2 = (12, "FFC4D79B")
|
||||||
|
RCUE2 = (13, "FFD8E4BC")
|
||||||
|
UE2 = (14, "FFEBF1DE")
|
||||||
|
BUT3 = (15, "FFFABF8F")
|
||||||
|
RCUE3 = (16, "FFFCD5B4")
|
||||||
|
UE3 = (17, "FFFDE9D9")
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_BORDERTHICKNESS(Enum):
|
||||||
|
def __new__(cls, value, width):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.width = width
|
||||||
|
return obj
|
||||||
|
|
||||||
|
BORDER_NONE = (1, None)
|
||||||
|
BORDER_HAIR = (2, "hair")
|
||||||
|
BORDER_THIN = (3, "thin")
|
||||||
|
BORDER_MEDIUM = (4, "medium")
|
||||||
|
BORDER_THICK = (5, "thick")
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_FONTNAME(Enum):
|
||||||
|
def __new__(cls, value, fontname):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.fontname = fontname
|
||||||
|
return obj
|
||||||
|
|
||||||
|
FONTNAME_ARIAL = (1, "Arial")
|
||||||
|
FONTNAME_COURIER = (2, "Courier New")
|
||||||
|
FONTNAME_CALIBRI = (3, "Calibri")
|
||||||
|
FONTNAME_TIMES = (4, "Times New Roman")
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_FONTSIZE(Enum):
|
||||||
|
def __new__(cls, value, fontsize):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.fontsize = fontsize
|
||||||
|
return obj
|
||||||
|
|
||||||
|
FONTSIZE_9 = (1, 9)
|
||||||
|
FONTSIZE_10 = (1, 10)
|
||||||
|
FONTSIZE_11 = (1, 11)
|
||||||
|
FONTSIZE_13 = (1, 13)
|
||||||
|
FONTSIZE_16 = (1, 16)
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_NUMBER_FORMAT(Enum):
|
||||||
|
def __new__(cls, value, format):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.format = format
|
||||||
|
return obj
|
||||||
|
|
||||||
|
NUMBER_GENERAL = (0, FORMAT_GENERAL)
|
||||||
|
NUMBER_00 = (1, FORMAT_NUMBER_00)
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_HALIGN(Enum):
|
||||||
|
def __new__(cls, value, position):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.position = position
|
||||||
|
return obj
|
||||||
|
|
||||||
|
HALIGN_CENTER = (1, "center")
|
||||||
|
HALIGN_RIGHT = (2, "right")
|
||||||
|
HALIGN_LEFT = (3, "left")
|
||||||
|
|
||||||
|
|
||||||
|
class SCO_VALIGN(Enum):
|
||||||
|
def __new__(cls, value, position):
|
||||||
|
obj = object.__new__(cls)
|
||||||
|
obj._value_ = value
|
||||||
|
obj.position = position
|
||||||
|
return obj
|
||||||
|
|
||||||
|
VALIGN_TOP = (1, "top")
|
||||||
|
VALIGN_BOTTOM = (2, "bottom")
|
||||||
|
VALIGN_CENTER = (3, "center")
|
||||||
|
|
||||||
|
|
||||||
|
free = 0
|
||||||
|
|
||||||
|
|
||||||
|
class Composante:
|
||||||
|
def __init__(self, base=None, width: int = 1):
|
||||||
|
global free
|
||||||
|
self.cache = {}
|
||||||
|
if base is None:
|
||||||
|
self.base = free
|
||||||
|
free += width
|
||||||
|
else:
|
||||||
|
self.base = base
|
||||||
|
self.width = width
|
||||||
|
self.end = self.base + self.width
|
||||||
|
self.mask = ((1 << width) - 1) << self.base
|
||||||
|
|
||||||
|
def read(self, signature: int) -> int:
|
||||||
|
return (signature & self.mask) >> self.base
|
||||||
|
|
||||||
|
def clear(self, signature: int) -> int:
|
||||||
|
return signature & ~self.mask
|
||||||
|
|
||||||
|
def write(self, index, signature=0) -> int:
|
||||||
|
return self.clear(signature) + index << self.base
|
||||||
|
|
||||||
|
def lookup_or_cache(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
if not value in self.cache:
|
||||||
|
self.cache[signature] = self.build(value)
|
||||||
|
return self.cache[value]
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def build(self, value: int):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_boolean(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=1)
|
||||||
|
|
||||||
|
def build(self, signature):
|
||||||
|
value = self.read(signature)
|
||||||
|
return value == 1
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_number_format(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=2)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_NUMBER_FORMAT(value) or None
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_Colors(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=5)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_COLORS(value) or SCO_COLORS.BLACK
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_borderThickness(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=2)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_BORDERTHICKNESS(value) or None
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_fontname(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=3)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_FONTNAME(value) or None
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_fontsize(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=3)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_FONTSIZE(value) or None
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_halign(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=2)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_HALIGN(value) or None
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_valign(Composante):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(width=2)
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
value = self.read(signature)
|
||||||
|
return SCO_VALIGN(signature) or None
|
||||||
|
|
||||||
|
|
||||||
|
class Sco_BorderSide:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
thickness: SCO_BORDERTHICKNESS = None,
|
||||||
|
color: SCO_COLORS = SCO_COLORS.WHITE,
|
||||||
|
):
|
||||||
|
self.thickness = thickness
|
||||||
|
self.color: SCO_COLORS = color
|
||||||
|
|
||||||
|
def get_openxl(self):
|
||||||
|
side: Side = Side(border_style=self.thickness.width, color=self.color.argb)
|
||||||
|
return side
|
||||||
|
|
||||||
|
|
||||||
|
class Sco_Borders:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
left: Sco_BorderSide = None,
|
||||||
|
right: Sco_BorderSide = None,
|
||||||
|
top: Sco_BorderSide = None,
|
||||||
|
bottom: Sco_BorderSide = None,
|
||||||
|
):
|
||||||
|
self.left = left
|
||||||
|
self.right = right
|
||||||
|
self.top = top
|
||||||
|
self.bottom = bottom
|
||||||
|
|
||||||
|
def get_openxl(self):
|
||||||
|
border: Border = Border(
|
||||||
|
left=self.left.get_openxl(),
|
||||||
|
right=self.right.get_openxl(),
|
||||||
|
top=self.top.get_openxl(),
|
||||||
|
bottom=self.bottom.get_openxl(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Sco_Alignment:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
halign: SCO_HALIGN = None,
|
||||||
|
valign: SCO_VALIGN = None,
|
||||||
|
):
|
||||||
|
self.halign = halign
|
||||||
|
self.valign = valign
|
||||||
|
|
||||||
|
def get_openxl(self):
|
||||||
|
al = openpyxl.styles.Alignment()
|
||||||
|
al.horizontal = self.halign.position
|
||||||
|
al.vertical = self.valign.position
|
||||||
|
return al
|
||||||
|
|
||||||
|
|
||||||
|
class Sco_Font:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str = None,
|
||||||
|
fontsize: int = None,
|
||||||
|
bold: bool = None,
|
||||||
|
italic: bool = None,
|
||||||
|
outline: bool = None,
|
||||||
|
color: "SCO_COLORS" = None,
|
||||||
|
):
|
||||||
|
self.name = name
|
||||||
|
self.bold = bold
|
||||||
|
self.italic = italic
|
||||||
|
self.outline = outline
|
||||||
|
self.color = color
|
||||||
|
self.fontsize = fontsize
|
||||||
|
|
||||||
|
|
||||||
|
class Sco_Style:
|
||||||
|
from openpyxl.cell import WriteOnlyCell, Cell
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
font: Sco_Font = None,
|
||||||
|
bgcolor: SCO_COLORS = None,
|
||||||
|
alignment: Sco_Alignment = None,
|
||||||
|
borders: Sco_Borders = None,
|
||||||
|
number_format: SCO_NUMBER_FORMAT = None,
|
||||||
|
):
|
||||||
|
self.font = font
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
self.alignment = alignment
|
||||||
|
self.borders = borders
|
||||||
|
self.number_format = number_format
|
||||||
|
|
||||||
|
def apply(self, cell: Cell):
|
||||||
|
if self.font:
|
||||||
|
cell.font = self.font.get_openxl()
|
||||||
|
if self.bgcolor:
|
||||||
|
cell.fill = PatternFill(fill_type="solid", fgColor=self.bgcolor.argb)
|
||||||
|
if self.alignment:
|
||||||
|
cell.alignment = self.alignment.get_openxl()
|
||||||
|
if self.borders:
|
||||||
|
cell.border = self.borders.get_openxl()
|
||||||
|
if self.number_format:
|
||||||
|
cell.number_format = self.number_format.get_openxl()
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_group(Composante):
|
||||||
|
def __init__(self, composantes: list[Composante]):
|
||||||
|
self.composantes = composantes
|
||||||
|
mini = min([comp.base for comp in composantes])
|
||||||
|
maxi = max([comp.end for comp in composantes])
|
||||||
|
width = sum([comp.width for comp in composantes])
|
||||||
|
if not width == (maxi - mini):
|
||||||
|
raise Exception("Composante group non complete ou non connexe")
|
||||||
|
super().__init__(base=mini, width=width)
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_font(Composante_group):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: Composante_fontname,
|
||||||
|
fontsize: Composante_fontsize,
|
||||||
|
color: Composante_Colors,
|
||||||
|
bold: Composante_boolean,
|
||||||
|
italic: Composante_boolean,
|
||||||
|
outline: Composante_boolean,
|
||||||
|
):
|
||||||
|
super().__init__([name, fontsize, color, bold, italic, outline])
|
||||||
|
self.name = name
|
||||||
|
self.fontsize = fontsize
|
||||||
|
self.color = color
|
||||||
|
self.bold = bold
|
||||||
|
self.italic = italic
|
||||||
|
self.outline = outline
|
||||||
|
|
||||||
|
def build(self, signature):
|
||||||
|
return Sco_Font(
|
||||||
|
name=self.name.lookup_or_cache(signature),
|
||||||
|
fontsize=self.fontsize.lookup_or_cache(signature),
|
||||||
|
color=self.color.lookup_or_cache(signature),
|
||||||
|
bold=self.bold.lookup_or_cache(signature),
|
||||||
|
italic=self.italic.lookup_or_cache(signature),
|
||||||
|
outline=self.outline.lookup_or_cache(signature),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_border(Composante_group):
|
||||||
|
def __init__(self, thick: Composante_borderThickness, color: Composante_Colors):
|
||||||
|
super().__init__([thick, color])
|
||||||
|
self.thick = thick
|
||||||
|
self.color = color
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
return Sco_BorderSide(
|
||||||
|
thickness=self.thick.lookup_or_cache(signature),
|
||||||
|
color=self.color.lookup_or_cache(signature),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_borders(Composante_group):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
left: Composante_border,
|
||||||
|
right: Composante_border,
|
||||||
|
top: Composante_border,
|
||||||
|
bottom: Composante_border,
|
||||||
|
):
|
||||||
|
super().__init__([left, right, top, bottom])
|
||||||
|
self.left = left
|
||||||
|
self.right = right
|
||||||
|
self.top = top
|
||||||
|
self.bottom = bottom
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
return Sco_Borders(
|
||||||
|
left=self.left.lookup_or_cache(signature),
|
||||||
|
right=self.right.lookup_or_cache(signature),
|
||||||
|
top=self.top.lookup_or_cache(signature),
|
||||||
|
bottom=self.bottom.lookup_or_cache(signature),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_alignment(Composante_group):
|
||||||
|
def __init__(self, halign: Composante_halign, valign: Composante_valign):
|
||||||
|
super().__init__([halign, valign])
|
||||||
|
self.halign = halign
|
||||||
|
self.valign = valign
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
return Sco_Alignment(
|
||||||
|
halign=self.halign.lookup_or_cache(signature),
|
||||||
|
valign=self.valign.lookup_or_cache(signature),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ALL = Composante_all(FONT, BGCOLOR, BORDERS, ALIGNMENT, NUMBER_FORMAT)
|
||||||
|
|
||||||
|
|
||||||
|
class Composante_all(Composante_group):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
font: Composante_font,
|
||||||
|
bgcolor: Composante_Colors,
|
||||||
|
borders: Composante_borders,
|
||||||
|
alignment: Composante_alignment,
|
||||||
|
number_format: Composante_number_format,
|
||||||
|
):
|
||||||
|
super().__init__([font, bgcolor, borders, alignment, number_format])
|
||||||
|
self.font = font
|
||||||
|
self.bgcolor = bgcolor
|
||||||
|
self.borders = borders
|
||||||
|
self.alignment = alignment
|
||||||
|
self.number_format = number_format
|
||||||
|
|
||||||
|
def build(self, signature: int):
|
||||||
|
return Sco_Style(
|
||||||
|
bgcolor=self.bgcolor.lookup_or_cache(signature),
|
||||||
|
font=self.font.lookup_or_cache(signature),
|
||||||
|
borders=self.borders.lookup_or_cache(signature),
|
||||||
|
alignment=self.alignment.lookup_or_cache(signature),
|
||||||
|
number_format=self.number_format.lookup_or_cache(signature),
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_style(self, signature: int):
|
||||||
|
return self.lookup_or_cache(signature)
|
||||||
|
|
||||||
|
|
||||||
|
class FMT(Enum):
|
||||||
|
def __init__(self, composante: Composante):
|
||||||
|
self.composante = composante
|
||||||
|
|
||||||
|
def write(self, value, signature=0) -> int:
|
||||||
|
return self.composante.write(value, signature)
|
||||||
|
|
||||||
|
def get_style(self, signature: int):
|
||||||
|
return self.composante.lookup_or_cache(signature)
|
||||||
|
|
||||||
|
FONT_NAME = Composante_fontname()
|
||||||
|
FONT_SIZE = Composante_fontsize()
|
||||||
|
FONT_COLOR = Composante_Colors()
|
||||||
|
FONT_BOLD = Composante_boolean()
|
||||||
|
FONT_ITALIC = Composante_boolean()
|
||||||
|
FONT_OUTLINE = Composante_boolean()
|
||||||
|
BORDER_LEFT_STYLE = Composante_borderThickness()
|
||||||
|
BORDER_LEFT_COLOR = Composante_Colors()
|
||||||
|
BORDER_RIGHT_STYLE = Composante_borderThickness()
|
||||||
|
BORDER_RIGHT_COLOR = Composante_Colors()
|
||||||
|
BORDER_TOP_STYLE = Composante_borderThickness()
|
||||||
|
BORDER_TOP_COLOR = Composante_Colors()
|
||||||
|
BORDER_BOTTOM_STYLE = Composante_borderThickness()
|
||||||
|
BORDER_BOTTOM_COLOR = Composante_Colors()
|
||||||
|
BGCOLOR = Composante_Colors()
|
||||||
|
ALIGNMENT_HALIGN = Composante_halign()
|
||||||
|
ALIGNEMENT_VALIGN = Composante_valign()
|
||||||
|
NUMBER_FORMAT = Composante_number_format()
|
||||||
|
FONT = Composante_font(
|
||||||
|
FONT_NAME, FONT_SIZE, FONT_COLOR, FONT_BOLD, FONT_ITALIC, FONT_OUTLINE
|
||||||
|
)
|
||||||
|
BORDER_LEFT = Composante_border(BORDER_LEFT_STYLE, BORDER_LEFT_COLOR)
|
||||||
|
BORDER_RIGHT = Composante_border(BORDER_RIGHT_STYLE, BORDER_RIGHT_COLOR)
|
||||||
|
BORDER_TOP = Composante_border(BORDER_TOP_STYLE, BORDER_TOP_COLOR)
|
||||||
|
BORDER_BOTTOM = Composante_border(BORDER_BOTTOM_STYLE, BORDER_BOTTOM_COLOR)
|
||||||
|
BORDERS = Composante_borders(BORDER_LEFT, BORDER_RIGHT, BORDER_TOP, BORDER_BOTTOM)
|
||||||
|
ALIGNMENT = Composante_alignment(ALIGNMENT_HALIGN, ALIGNMENT_HALIGN)
|
||||||
|
ALL = Composante_all(FONT, BGCOLOR, BORDERS, ALIGNMENT, NUMBER_FORMAT)
|
@ -53,15 +53,10 @@ import json
|
|||||||
from pandas import read_csv
|
from pandas import read_csv
|
||||||
|
|
||||||
from setup_test_api import (
|
from setup_test_api import (
|
||||||
API_PASSWORD,
|
|
||||||
API_URL,
|
|
||||||
API_USER,
|
|
||||||
APIError,
|
|
||||||
CHECK_CERTIFICATE,
|
CHECK_CERTIFICATE,
|
||||||
get_auth_headers,
|
get_auth_headers,
|
||||||
GET,
|
GET,
|
||||||
POST_JSON,
|
POST_JSON,
|
||||||
SCODOC_URL,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
DATA_DIR = "/tmp/samples/"
|
DATA_DIR = "/tmp/samples/"
|
||||||
|
Loading…
Reference in New Issue
Block a user