# sumaexcel/conditional.py from typing import Dict, Any, List, Union from openpyxl.formatting.rule import Rule, ColorScaleRule, DataBarRule, IconSetRule from openpyxl.styles import PatternFill, Font, Border, Side from openpyxl.worksheet.worksheet import Worksheet class ConditionalFormatManager: """Handle conditional formatting in Excel""" def __init__(self, worksheet: Worksheet): self.worksheet = worksheet def add_color_scale( self, cell_range: str, min_color: str = "00FF0000", # Red mid_color: str = "00FFFF00", # Yellow max_color: str = "0000FF00" # Green ) -> None: """Add color scale conditional formatting""" rule = ColorScaleRule( start_type='min', start_color=min_color, mid_type='percentile', mid_value=50, mid_color=mid_color, end_type='max', end_color=max_color ) self.worksheet.conditional_formatting.add(cell_range, rule) def add_data_bar( self, cell_range: str, color: str = "000000FF", # Blue show_value: bool = True ) -> None: """Add data bar conditional formatting""" rule = DataBarRule( start_type='min', end_type='max', color=color, showValue=show_value ) self.worksheet.conditional_formatting.add(cell_range, rule) def add_icon_set( self, cell_range: str, icon_style: str = '3Arrows', # '3Arrows', '3TrafficLights', '3Signs' reverse_icons: bool = False ) -> None: """Add icon set conditional formatting""" rule = IconSetRule( icon_style=icon_style, type='percent', values=[0, 33, 67], reverse_icons=reverse_icons ) self.worksheet.conditional_formatting.add(cell_range, rule) def add_custom_rule( self, cell_range: str, rule_type: str, formula: str, fill_color: str = None, font_color: str = None, bold: bool = None, border_style: str = None, border_color: str = None ) -> None: """Add custom conditional formatting rule""" dxf = {} if fill_color: dxf['fill'] = PatternFill(start_color=fill_color, end_color=fill_color) if font_color or bold is not None: dxf['font'] = Font(color=font_color, bold=bold) if border_style and border_color: side = Side(style=border_style, color=border_color) dxf['border'] = Border(left=side, right=side, top=side, bottom=side) rule = Rule(type=rule_type, formula=[formula], dxf=dxf) self.worksheet.conditional_formatting.add(cell_range, rule) def copy_conditional_format( self, source_range: str, target_range: str ) -> None: """Copy conditional formatting from one range to another""" source_rules = self.worksheet.conditional_formatting.get(source_range) if source_rules: for rule in source_rules: self.worksheet.conditional_formatting.add(target_range, rule) def clear_conditional_format( self, cell_range: str ) -> None: """Clear conditional formatting from specified range""" self.worksheet.conditional_formatting.delete(cell_range)