103 lines
3.4 KiB
Python
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)
|