Загрузка данных
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()