diff options
author | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
---|---|---|
committer | S. Solomon Darnell | 2025-03-28 21:52:21 -0500 |
commit | 4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch) | |
tree | ee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/openpyxl/formatting | |
parent | cc961e04ba734dd72309fb548a2f97d67d578813 (diff) | |
download | gn-ai-master.tar.gz |
Diffstat (limited to '.venv/lib/python3.12/site-packages/openpyxl/formatting')
3 files changed, 408 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/openpyxl/formatting/__init__.py b/.venv/lib/python3.12/site-packages/openpyxl/formatting/__init__.py new file mode 100644 index 00000000..bedc2bc4 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/formatting/__init__.py @@ -0,0 +1,3 @@ +# Copyright (c) 2010-2024 openpyxl + +from .rule import Rule diff --git a/.venv/lib/python3.12/site-packages/openpyxl/formatting/formatting.py b/.venv/lib/python3.12/site-packages/openpyxl/formatting/formatting.py new file mode 100644 index 00000000..bf622bf9 --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/formatting/formatting.py @@ -0,0 +1,114 @@ +# Copyright (c) 2010-2024 openpyxl + +from collections import OrderedDict + +from openpyxl.descriptors import ( + Bool, + Sequence, + Alias, + Convertible, +) +from openpyxl.descriptors.serialisable import Serialisable + +from .rule import Rule + +from openpyxl.worksheet.cell_range import MultiCellRange + +class ConditionalFormatting(Serialisable): + + tagname = "conditionalFormatting" + + sqref = Convertible(expected_type=MultiCellRange) + cells = Alias("sqref") + pivot = Bool(allow_none=True) + cfRule = Sequence(expected_type=Rule) + rules = Alias("cfRule") + + + def __init__(self, sqref=(), pivot=None, cfRule=(), extLst=None): + self.sqref = sqref + self.pivot = pivot + self.cfRule = cfRule + + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + return self.sqref == other.sqref + + + def __hash__(self): + return hash(self.sqref) + + + def __repr__(self): + return "<{cls} {cells}>".format(cls=self.__class__.__name__, cells=self.sqref) + + + def __contains__(self, coord): + """ + Check whether a certain cell is affected by the formatting + """ + return coord in self.sqref + + +class ConditionalFormattingList: + """Conditional formatting rules.""" + + + def __init__(self): + self._cf_rules = OrderedDict() + self.max_priority = 0 + + + def add(self, range_string, cfRule): + """Add a rule such as ColorScaleRule, FormulaRule or CellIsRule + + The priority will be added automatically. + """ + cf = range_string + if isinstance(range_string, str): + cf = ConditionalFormatting(range_string) + if not isinstance(cfRule, Rule): + raise ValueError("Only instances of openpyxl.formatting.rule.Rule may be added") + rule = cfRule + self.max_priority += 1 + if not rule.priority: + rule.priority = self.max_priority + + self._cf_rules.setdefault(cf, []).append(rule) + + + def __bool__(self): + return bool(self._cf_rules) + + + def __len__(self): + return len(self._cf_rules) + + + def __iter__(self): + for cf, rules in self._cf_rules.items(): + cf.rules = rules + yield cf + + + def __getitem__(self, key): + """ + Get the rules for a cell range + """ + if isinstance(key, str): + key = ConditionalFormatting(sqref=key) + return self._cf_rules[key] + + + def __delitem__(self, key): + key = ConditionalFormatting(sqref=key) + del self._cf_rules[key] + + + def __setitem__(self, key, rule): + """ + Add a rule for a cell range + """ + self.add(key, rule) diff --git a/.venv/lib/python3.12/site-packages/openpyxl/formatting/rule.py b/.venv/lib/python3.12/site-packages/openpyxl/formatting/rule.py new file mode 100644 index 00000000..c4ba7f8f --- /dev/null +++ b/.venv/lib/python3.12/site-packages/openpyxl/formatting/rule.py @@ -0,0 +1,291 @@ +# Copyright (c) 2010-2024 openpyxl + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.descriptors import ( + Typed, + String, + Sequence, + Bool, + NoneSet, + Set, + Integer, + Float, +) +from openpyxl.descriptors.excel import ExtensionList +from openpyxl.styles.colors import Color, ColorDescriptor +from openpyxl.styles.differential import DifferentialStyle + +from openpyxl.utils.cell import COORD_RE + + +class ValueDescriptor(Float): + """ + Expected type depends upon type attribute of parent :-( + + Most values should be numeric BUT they can also be cell references + """ + + def __set__(self, instance, value): + ref = None + if value is not None and isinstance(value, str): + ref = COORD_RE.match(value) + if instance.type == "formula" or ref: + self.expected_type = str + else: + self.expected_type = float + super().__set__(instance, value) + + +class FormatObject(Serialisable): + + tagname = "cfvo" + + type = Set(values=(['num', 'percent', 'max', 'min', 'formula', 'percentile'])) + val = ValueDescriptor(allow_none=True) + gte = Bool(allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + + __elements__ = () + + def __init__(self, + type, + val=None, + gte=None, + extLst=None, + ): + self.type = type + self.val = val + self.gte = gte + + +class RuleType(Serialisable): + + cfvo = Sequence(expected_type=FormatObject) + + +class IconSet(RuleType): + + tagname = "iconSet" + + iconSet = NoneSet(values=(['3Arrows', '3ArrowsGray', '3Flags', + '3TrafficLights1', '3TrafficLights2', '3Signs', '3Symbols', '3Symbols2', + '4Arrows', '4ArrowsGray', '4RedToBlack', '4Rating', '4TrafficLights', + '5Arrows', '5ArrowsGray', '5Rating', '5Quarters'])) + showValue = Bool(allow_none=True) + percent = Bool(allow_none=True) + reverse = Bool(allow_none=True) + + __elements__ = ("cfvo",) + + def __init__(self, + iconSet=None, + showValue=None, + percent=None, + reverse=None, + cfvo=None, + ): + self.iconSet = iconSet + self.showValue = showValue + self.percent = percent + self.reverse = reverse + self.cfvo = cfvo + + +class DataBar(RuleType): + + tagname = "dataBar" + + minLength = Integer(allow_none=True) + maxLength = Integer(allow_none=True) + showValue = Bool(allow_none=True) + color = ColorDescriptor() + + __elements__ = ('cfvo', 'color') + + def __init__(self, + minLength=None, + maxLength=None, + showValue=None, + cfvo=None, + color=None, + ): + self.minLength = minLength + self.maxLength = maxLength + self.showValue = showValue + self.cfvo = cfvo + self.color = color + + +class ColorScale(RuleType): + + tagname = "colorScale" + + color = Sequence(expected_type=Color) + + __elements__ = ('cfvo', 'color') + + def __init__(self, + cfvo=None, + color=None, + ): + self.cfvo = cfvo + self.color = color + + +class Rule(Serialisable): + + tagname = "cfRule" + + type = Set(values=(['expression', 'cellIs', 'colorScale', 'dataBar', + 'iconSet', 'top10', 'uniqueValues', 'duplicateValues', 'containsText', + 'notContainsText', 'beginsWith', 'endsWith', 'containsBlanks', + 'notContainsBlanks', 'containsErrors', 'notContainsErrors', 'timePeriod', + 'aboveAverage'])) + dxfId = Integer(allow_none=True) + priority = Integer() + stopIfTrue = Bool(allow_none=True) + aboveAverage = Bool(allow_none=True) + percent = Bool(allow_none=True) + bottom = Bool(allow_none=True) + operator = NoneSet(values=(['lessThan', 'lessThanOrEqual', 'equal', + 'notEqual', 'greaterThanOrEqual', 'greaterThan', 'between', 'notBetween', + 'containsText', 'notContains', 'beginsWith', 'endsWith'])) + text = String(allow_none=True) + timePeriod = NoneSet(values=(['today', 'yesterday', 'tomorrow', 'last7Days', + 'thisMonth', 'lastMonth', 'nextMonth', 'thisWeek', 'lastWeek', + 'nextWeek'])) + rank = Integer(allow_none=True) + stdDev = Integer(allow_none=True) + equalAverage = Bool(allow_none=True) + formula = Sequence(expected_type=str) + colorScale = Typed(expected_type=ColorScale, allow_none=True) + dataBar = Typed(expected_type=DataBar, allow_none=True) + iconSet = Typed(expected_type=IconSet, allow_none=True) + extLst = Typed(expected_type=ExtensionList, allow_none=True) + dxf = Typed(expected_type=DifferentialStyle, allow_none=True) + + __elements__ = ('colorScale', 'dataBar', 'iconSet', 'formula') + __attrs__ = ('type', 'rank', 'priority', 'equalAverage', 'operator', + 'aboveAverage', 'dxfId', 'stdDev', 'stopIfTrue', 'timePeriod', 'text', + 'percent', 'bottom') + + + def __init__(self, + type, + dxfId=None, + priority=0, + stopIfTrue=None, + aboveAverage=None, + percent=None, + bottom=None, + operator=None, + text=None, + timePeriod=None, + rank=None, + stdDev=None, + equalAverage=None, + formula=(), + colorScale=None, + dataBar=None, + iconSet=None, + extLst=None, + dxf=None, + ): + self.type = type + self.dxfId = dxfId + self.priority = priority + self.stopIfTrue = stopIfTrue + self.aboveAverage = aboveAverage + self.percent = percent + self.bottom = bottom + self.operator = operator + self.text = text + self.timePeriod = timePeriod + self.rank = rank + self.stdDev = stdDev + self.equalAverage = equalAverage + self.formula = formula + self.colorScale = colorScale + self.dataBar = dataBar + self.iconSet = iconSet + self.dxf = dxf + + +def ColorScaleRule(start_type=None, + start_value=None, + start_color=None, + mid_type=None, + mid_value=None, + mid_color=None, + end_type=None, + end_value=None, + end_color=None): + + """Backwards compatibility""" + formats = [] + if start_type is not None: + formats.append(FormatObject(type=start_type, val=start_value)) + if mid_type is not None: + formats.append(FormatObject(type=mid_type, val=mid_value)) + if end_type is not None: + formats.append(FormatObject(type=end_type, val=end_value)) + colors = [] + for v in (start_color, mid_color, end_color): + if v is not None: + if not isinstance(v, Color): + v = Color(v) + colors.append(v) + cs = ColorScale(cfvo=formats, color=colors) + rule = Rule(type="colorScale", colorScale=cs) + return rule + + +def FormulaRule(formula=None, stopIfTrue=None, font=None, border=None, + fill=None): + """ + Conditional formatting with custom differential style + """ + rule = Rule(type="expression", formula=formula, stopIfTrue=stopIfTrue) + rule.dxf = DifferentialStyle(font=font, border=border, fill=fill) + return rule + + +def CellIsRule(operator=None, formula=None, stopIfTrue=None, font=None, border=None, fill=None): + """ + Conditional formatting rule based on cell contents. + """ + # Excel doesn't use >, >=, etc, but allow for ease of python development + expand = {">": "greaterThan", ">=": "greaterThanOrEqual", "<": "lessThan", "<=": "lessThanOrEqual", + "=": "equal", "==": "equal", "!=": "notEqual"} + + operator = expand.get(operator, operator) + + rule = Rule(type='cellIs', operator=operator, formula=formula, stopIfTrue=stopIfTrue) + rule.dxf = DifferentialStyle(font=font, border=border, fill=fill) + + return rule + + +def IconSetRule(icon_style=None, type=None, values=None, showValue=None, percent=None, reverse=None): + """ + Convenience function for creating icon set rules + """ + cfvo = [] + for val in values: + cfvo.append(FormatObject(type, val)) + icon_set = IconSet(iconSet=icon_style, cfvo=cfvo, showValue=showValue, + percent=percent, reverse=reverse) + rule = Rule(type='iconSet', iconSet=icon_set) + + return rule + + +def DataBarRule(start_type=None, start_value=None, end_type=None, + end_value=None, color=None, showValue=None, minLength=None, maxLength=None): + start = FormatObject(start_type, start_value) + end = FormatObject(end_type, end_value) + data_bar = DataBar(cfvo=[start, end], color=color, showValue=showValue, + minLength=minLength, maxLength=maxLength) + rule = Rule(type='dataBar', dataBar=data_bar) + + return rule |