Files
rogaining_srv/SumasenLibs/excel_lib/sumaexcel/conditional.py
2024-11-03 10:49:42 +00:00

103 lines
3.4 KiB
Python

# 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)