| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- """
- Multi-theme color and visual style manager for the universal data report generator.
- """
- from pptx.dml.color import RGBColor
- from report_config import ThemeConfig, ThemePreset
- PRESETS = {
- ThemePreset.BUSINESS_CLASSIC: ThemeConfig(
- preset=ThemePreset.BUSINESS_CLASSIC,
- name='商务经典',
- primary='#1E3A5F',
- accent='#10B981',
- accent_neg='#EF4444',
- secondary='#64748B',
- dark='#1F3A5C',
- white='#FFFFFF',
- gray_bg='#F2F2F2',
- card_bg='#E7F0F7',
- text='#333333',
- text_gray='#666666',
- line='#D9D9D9',
- chart_series=[
- '#1E3A5F', '#10B981', '#ED7D31', '#64748B',
- '#EF4444', '#707070', '#4472C4', '#5B9BD5',
- ],
- ),
- ThemePreset.FRESH_SIMPLE: ThemeConfig(
- preset=ThemePreset.FRESH_SIMPLE,
- name='清新简约',
- primary='#1B8A5E',
- accent='#10B981',
- accent_neg='#EF4444',
- secondary='#94A3B8',
- dark='#0F5C3B',
- white='#FFFFFF',
- gray_bg='#F8FAFC',
- card_bg='#ECFDF5',
- text='#1E293B',
- text_gray='#64748B',
- line='#E2E8F0',
- chart_series=[
- '#1B8A5E', '#3B82F6', '#F59E0B', '#94A3B8',
- '#EF4444', '#8B5CF6', '#06B6D4', '#10B981',
- ],
- ),
- ThemePreset.DARK_PROFESSIONAL: ThemeConfig(
- preset=ThemePreset.DARK_PROFESSIONAL,
- name='深色专业',
- primary='#1E293B',
- accent='#38BDF8',
- accent_neg='#F87171',
- secondary='#94A3B8',
- dark='#0F172A',
- white='#FFFFFF',
- gray_bg='#F1F5F9',
- card_bg='#E2E8F0',
- text='#1E293B',
- text_gray='#475569',
- line='#CBD5E1',
- chart_series=[
- '#1E293B', '#38BDF8', '#F59E0B', '#94A3B8',
- '#F87171', '#A78BFA', '#34D399', '#FB923C',
- ],
- ),
- ThemePreset.WARM_BRAND: ThemeConfig(
- preset=ThemePreset.WARM_BRAND,
- name='温暖品牌',
- primary='#C2410C',
- accent='#F97316',
- accent_neg='#DC2626',
- secondary='#78716C',
- dark='#7C2D12',
- white='#FFFFFF',
- gray_bg='#FFFBEB',
- card_bg='#FFF7ED',
- text='#292524',
- text_gray='#78716C',
- line='#D6D3D1',
- chart_series=[
- '#C2410C', '#F97316', '#EAB308', '#78716C',
- '#DC2626', '#84CC16', '#06B6D4', '#A855F7',
- ],
- ),
- }
- def get_theme(preset: ThemePreset, custom_overrides: dict = None) -> ThemeConfig:
- if preset == ThemePreset.CUSTOM:
- config = ThemeConfig(preset=ThemePreset.CUSTOM, name='自定义主题')
- if custom_overrides:
- for k, v in custom_overrides.items():
- if hasattr(config, k):
- setattr(config, k, v)
- return config
- return PRESETS.get(preset, PRESETS[ThemePreset.BUSINESS_CLASSIC])
- def theme_to_rgb_colors(theme: ThemeConfig) -> dict:
- return {
- 'primary': _hex_to_rgb(theme.primary),
- 'accent': _hex_to_rgb(theme.accent),
- 'accent_neg': _hex_to_rgb(theme.accent_neg),
- 'secondary': _hex_to_rgb(theme.secondary),
- 'dark': _hex_to_rgb(theme.dark),
- 'white': _hex_to_rgb(theme.white),
- 'gray_bg': _hex_to_rgb(theme.gray_bg),
- 'card_bg': _hex_to_rgb(theme.card_bg),
- 'text': _hex_to_rgb(theme.text),
- 'text_gray': _hex_to_rgb(theme.text_gray),
- 'line': _hex_to_rgb(theme.line),
- 'green': _hex_to_rgb(theme.accent),
- 'red': _hex_to_rgb(theme.accent_neg),
- 'orange': _hex_to_rgb(theme.chart_series[2]) if len(theme.chart_series) > 2 else RGBColor(0xED, 0x7D, 0x31),
- 'series': [_hex_to_rgb(c) for c in theme.chart_series],
- }
- def _hex_to_rgb(hex_str: str) -> RGBColor:
- hex_str = hex_str.lstrip('#')
- if len(hex_str) == 6:
- return RGBColor(int(hex_str[0:2], 16), int(hex_str[2:4], 16), int(hex_str[4:6], 16))
- return RGBColor(0x33, 0x33, 0x33)
- def list_themes() -> list[dict]:
- result = []
- for preset, config in PRESETS.items():
- result.append({
- 'key': preset.value,
- 'name': config.name,
- 'primary': config.primary,
- 'accent': config.accent,
- })
- result.append({
- 'key': 'custom',
- 'name': '自定义主题',
- 'primary': '自定义',
- 'accent': '自定义',
- })
- return result
- if __name__ == '__main__':
- for t in list_themes():
- print(f"{t['key']}: {t['name']} (primary={t['primary']}, accent={t['accent']})")
|