Загрузка данных


import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter

def create_workout_plan():
    wb = openpyxl.Workbook()
    wb.remove(wb.active)

    # ---------- стили ----------
    header_font = Font(name='Calibri', bold=True, size=11, color='FFFFFF')
    header_fill = PatternFill(start_color='2F5496', end_color='2F5496', fill_type='solid')
    day_font = Font(name='Calibri', bold=True, size=11)
    day_fill = PatternFill(start_color='D6E4F0', end_color='D6E4F0', fill_type='solid')
    normal_font = Font(name='Calibri', size=11)
    center_align = Alignment(horizontal='center', vertical='center')
    left_align = Alignment(horizontal='left', vertical='center')
    thin_border = Border(
        left=Side(style='thin'), right=Side(style='thin'),
        top=Side(style='thin'), bottom=Side(style='thin')
    )

    columns = ['День', 'Упражнение', 'Подходы', 'Повторения', 'RPE', 'Отдых']
    col_widths = [8, 40, 10, 14, 8, 14]

    # ---------- данные по неделям ----------
    weeks = {
        'Тяжёлая неделя': [
            ('ПН', 'Бабочка', 2, '10–12', 7, '60–90 сек'),
            ('ПН', 'Жим гантелей лёжа', 4, '6–8', '8–9', '2–3 мин'),
            ('ПН', 'Брусья с весом', 3, '6–8', 9, '2–3 мин'),
            ('ПН', 'Жим гантелей сидя', 3, '8–10', 8, '2 мин'),
            ('ПН', 'Махи в стороны', 3, '12–15', 8, '60–90 сек'),
            ('ПН', 'Трицепс в тренажёре', 2, '10–12', 8, '60–90 сек'),
            ('ПН', 'Французский жим лёжа', 2, '10–12', 8, '60–90 сек'),
            ('СР', 'Пуловер', 3, '12–15', 7, '60–90 сек'),
            ('СР', 'Подтягивания с весом', 4, '6–8', '8–9', '2–3 мин'),
            ('СР', 'Тяга штанги в наклоне', 4, '6–8', 9, '2–3 мин'),
            ('СР', 'Подъём штанги на бицепс стоя', 3, '8–10', 8, '2 мин'),
            ('СР', 'Молотковые сгибания', 3, '10–12', 8, '60–90 сек'),
            ('СР', 'Разведения в наклоне', 3, '12–15', 8, '60–90 сек'),
            ('ПТ', 'Разгибания ног сидя', 3, '12–15', 7, '60–90 сек'),
            ('ПТ', 'Приседания со штангой', 4, '6–8', 9, '2–3 мин'),
            ('ПТ', 'Румынская тяга', 4, '8–10', 8, '2–3 мин'),
            ('ПТ', 'Жим гантелей сидя', 3, '8–10', 8, '2 мин'),
            ('ПТ', 'Суперсет: махи + разведения в наклоне', 3, '12–15 каждое', 8, '60–90 сек'),
            ('ПТ', 'Сгибания ног сидя', 3, '10–12', 8, '60–90 сек'),
            ('ПТ', 'Подъёмы на носки стоя', 4, '15–20', '8–9', '60 сек'),
            ('СБ', 'Подъём штанги на бицепс стоя', 3, '6–8', 9, '2–3 мин'),
            ('СБ', 'Жим лёжа узким хватом', 3, '6–8', 9, '2–3 мин'),
            ('СБ', 'Молотковые сгибания', 3, '8–10', 9, '2 мин'),
            ('СБ', 'Французский жим сидя (гантель/блок)', 3, '8–10', 9, '2 мин'),
            ('СБ', 'Махи гантелей в стороны', 3, '10–12', 8, '60–90 сек'),
            ('СБ', 'Скамья Скотта', 2, '8–10', 8, '60–90 сек'),
            ('СБ', 'Разгибания на блоке с канатом', 2, '8–10', 8, '60–90 сек'),
        ],
        'Средняя неделя': [
            ('ПН', 'Бабочка', 2, '12–15', 6, '60–90 сек'),
            ('ПН', 'Жим гантелей лёжа', 4, '8–10', 8, '2 мин'),
            ('ПН', 'Брусья с весом', 3, '8–10', 8, '2 мин'),
            ('ПН', 'Жим гантелей сидя', 3, '10–12', '7–8', '2 мин'),
            ('ПН', 'Махи в стороны', 3, '14–17', '7–8', '60–90 сек'),
            ('ПН', 'Трицепс в тренажёре', 2, '12–15', '7–8', '60–90 сек'),
            ('ПН', 'Французский жим лёжа', 2, '12–15', '7–8', '60–90 сек'),
            ('СР', 'Пуловер', 3, '15–18', 6, '60–90 сек'),
            ('СР', 'Подтягивания с весом', 4, '8–10', 8, '2 мин'),
            ('СР', 'Тяга штанги в наклоне', 4, '8–10', 8, '2 мин'),
            ('СР', 'Подъём штанги на бицепс стоя', 3, '10–12', '7–8', '2 мин'),
            ('СР', 'Молотковые сгибания', 3, '12–15', '7–8', '60–90 сек'),
            ('СР', 'Разведения в наклоне', 3, '15–18', '7–8', '60–90 сек'),
            ('ПТ', 'Разгибания ног сидя', 3, '15–18', 6, '60–90 сек'),
            ('ПТ', 'Приседания со штангой', 4, '8–10', 8, '2 мин'),
            ('ПТ', 'Румынская тяга', 4, '10–12', '7–8', '2 мин'),
            ('ПТ', 'Жим гантелей сидя', 3, '10–12', '7–8', '2 мин'),
            ('ПТ', 'Суперсет: махи + разведения в наклоне', 3, '15–18 каждое', '7–8', '60–90 сек'),
            ('ПТ', 'Сгибания ног сидя', 3, '12–15', '7–8', '60–90 сек'),
            ('ПТ', 'Подъёмы на носки стоя', 4, '18–22', '7–8', '60 сек'),
            ('СБ', 'Подъём штанги на бицепс стоя', 3, '8–12', '7–8', '2 мин'),
            ('СБ', 'Жим лёжа узким хватом', 3, '8–12', '7–8', '2 мин'),
            ('СБ', 'Молотковые сгибания', 3, '10–12', '7–8', '60–90 сек'),
            ('СБ', 'Французский жим сидя', 3, '10–12', '7–8', '60–90 сек'),
            ('СБ', 'Махи гантелей в стороны', 3, '12–15', '7–8', '60–90 сек'),
            ('СБ', 'Скамья Скотта', 2, '10–12', 8, '60–90 сек'),
            ('СБ', 'Разгибания на блоке с канатом', 2, '10–12', 8, '60–90 сек'),
        ],
        'Лёгкая неделя': [
            ('ПН', 'Бабочка', 2, '15–18', 5, '60 сек'),
            ('ПН', 'Жим гантелей лёжа', 3, '10–12', 6, '1.5–2 мин'),
            ('ПН', 'Брусья без веса', 3, '10–12', '5–6', '1.5–2 мин'),
            ('ПН', 'Жим гантелей сидя', 3, '12–15', 6, '1.5–2 мин'),
            ('ПН', 'Махи в стороны', 3, '15–20', '5–6', '60 сек'),
            ('ПН', 'Трицепс в тренажёре', 2, '15–18', 6, '60 сек'),
            ('ПН', 'Французский жим лёжа', 2, '15–18', 6, '60 сек'),
            ('СР', 'Пуловер', 3, '15–20', 5, '60 сек'),
            ('СР', 'Подтягивания без веса', 3, '8–10', '5–6', '1.5–2 мин'),
            ('СР', 'Тяга штанги в наклоне лёгкая', 3, '10–12', 6, '1.5–2 мин'),
            ('СР', 'Подъём штанги на бицепс стоя лёгкая', 3, '12–15', 6, '1.5 мин'),
            ('СР', 'Молотковые сгибания лёгкие', 3, '15–18', 6, '60 сек'),
            ('СР', 'Разведения в наклоне лёгкие', 3, '15–20', '5–6', '60 сек'),
            ('ПТ', 'Разгибания ног сидя', 3, '18–20', 5, '60 сек'),
            ('ПТ', 'Приседания со штангой (50–60%)', 3, '10–12', 6, '1.5–2 мин'),
            ('ПТ', 'Румынская тяга лёгкая', 3, '12–15', 6, '1.5–2 мин'),
            ('ПТ', 'Жим гантелей сидя лёгкий', 3, '12–15', 6, '1.5–2 мин'),
            ('ПТ', 'Суперсет: махи + разведения лёгкие', 3, '15–20 каждое', '5–6', '60 сек'),
            ('ПТ', 'Сгибания ног сидя лёгкие', 3, '15', '5–6', '60 сек'),
            ('ПТ', 'Подъёмы на носки стоя лёгкие', 3, '20–25', 5, '60 сек'),
            ('СБ', 'Подъём штанги на бицепс стоя', 3, '12–15', '6–7', '1.5–2 мин'),
            ('СБ', 'Жим лёжа узким хватом', 3, '12–15', '6–7', '1.5–2 мин'),
            ('СБ', 'Молотковые сгибания', 3, '15–18', 6, '60–90 сек'),
            ('СБ', 'Французский жим сидя', 3, '15–18', 6, '60–90 сек'),
            ('СБ', 'Махи гантелей в стороны', 3, '15–20', 6, '60 сек'),
            ('СБ', 'Скамья Скотта', 2, '15–20', 7, '60 сек'),
            ('СБ', 'Разгибания на блоке с канатом', 2, '15–20', 6, '60 сек'),
        ],
        'Силовая неделя': [
            ('ПН', 'Бабочка', 2, '6–8', 8, '60–90 сек'),
            ('ПН', 'Жим гантелей лёжа', 5, '3–5', 10, '3–4 мин'),
            ('ПН', 'Брусья с весом', 4, '3–5', 10, '3–4 мин'),
            ('ПН', 'Жим гантелей сидя', 4, '5–6', 9, '2–3 мин'),
            ('ПН', 'Махи в стороны', 2, '10–12', 8, '60–90 сек'),
            ('ПН', 'Трицепс в тренажёре', 2, '8–10', 9, '2 мин'),
            ('СР', 'Пуловер', 2, '8–10', 9, '2 мин'),
            ('СР', 'Подтягивания с весом', 5, '3–5', 10, '3–4 мин'),
            ('СР', 'Тяга штанги в наклоне', 5, '3–5', 10, '3–4 мин'),
            ('СР', 'Подъём штанги на бицепс стоя', 3, '6–8', 9, '2–3 мин'),
            ('СР', 'Разведения в наклоне', 2, '10–12', 8, '60–90 сек'),
            ('ПТ', 'Разгибания ног сидя', 3, '8–10', 9, '2 мин'),
            ('ПТ', 'Приседания со штангой', 5, '3–5', 10, '3–4 мин'),
            ('ПТ', 'Румынская тяга', 4, '5–6', '9–10', '3 мин'),
            ('ПТ', 'Жим гантелей сидя', 4, '5–6', 9, '2–3 мин'),
            ('ПТ', 'Подъёмы на носки стоя', 4, '8–10', 9, '60–90 сек'),
            ('СБ', 'Подъём штанги на бицепс стоя', 4, '5–6', '9–10', '3 мин'),
            ('СБ', 'Жим лёжа узким хватом', 4, '5–6', '9–10', '3 мин'),
            ('СБ', 'Молотковые сгибания', 3, '6–8', 9, '2–3 мин'),
            ('СБ', 'Французский жим сидя', 3, '6–8', 9, '2–3 мин'),
            ('СБ', 'Махи гантелей в стороны', 3, '8–10', 8, '60–90 сек'),
        ]
    }

    # ---------- создаём листы недель ----------
    for week_name, data in weeks.items():
        ws = wb.create_sheet(title=week_name)
        for col_idx, header in enumerate(columns, 1):
            cell = ws.cell(row=1, column=col_idx, value=header)
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = center_align
            cell.border = thin_border

        current_day = None
        for row_idx, (day, exercise, sets, reps, rpe, rest) in enumerate(data, 2):
            values = [day, exercise, sets, reps, rpe, rest]
            for col_idx, val in enumerate(values, 1):
                cell = ws.cell(row=row_idx, column=col_idx, value=val)
                cell.font = normal_font
                cell.alignment = left_align if col_idx == 2 else center_align
                cell.border = thin_border
                if day in ('ПН', 'ПТ'):
                    cell.fill = PatternFill(start_color='F2F2F2', end_color='F2F2F2', fill_type='solid')
                elif day == 'СР':
                    cell.fill = PatternFill(start_color='E6F0FF', end_color='E6F0FF', fill_type='solid')
                elif day == 'СБ':
                    cell.fill = PatternFill(start_color='FFF2CC', end_color='FFF2CC', fill_type='solid')

        for col_idx, width in enumerate(col_widths, 1):
            ws.column_dimensions[get_column_letter(col_idx)].width = width
        ws.freeze_panes = 'A2'

    # ---------- лист "Рабочие веса" ----------
    # Собираем все уникальные упражнения (без дубликатов)
    all_exercises = set()
    for data in weeks.values():
        for row in data:
            all_exercises.add(row[1])  # row[1] — название упражнения
    sorted_exercises = sorted(all_exercises)

    ws_weights = wb.create_sheet(title='Рабочие веса')
    weight_columns = ['Упражнение', 'Тяжёлая неделя', 'Средняя неделя', 'Лёгкая неделя', 'Силовая неделя']
    weight_col_widths = [40, 16, 16, 16, 16]

    for col_idx, header in enumerate(weight_columns, 1):
        cell = ws_weights.cell(row=1, column=col_idx, value=header)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = center_align
        cell.border = thin_border

    for row_idx, exercise in enumerate(sorted_exercises, 2):
        cell_ex = ws_weights.cell(row=row_idx, column=1, value=exercise)
        cell_ex.font = normal_font
        cell_ex.alignment = left_align
        cell_ex.border = thin_border
        # пустые ячейки для весов с рамкой
        for col_idx in range(2, 6):
            cell = ws_weights.cell(row=row_idx, column=col_idx, value='')
            cell.font = normal_font
            cell.alignment = center_align
            cell.border = thin_border
            cell.number_format = '0.0'  # чтобы вес отображался как число с одним знаком

    for col_idx, width in enumerate(weight_col_widths, 1):
        ws_weights.column_dimensions[get_column_letter(col_idx)].width = width
    ws_weights.freeze_panes = 'B2'  # закрепляем столбец с упражнениями и строку заголовка

    wb.save('training_plan_arms.xlsx')
    print('Файл training_plan_arms.xlsx создан с 5 листами, включая "Рабочие веса".')

if __name__ == '__main__':
    create_workout_plan()