# -*- coding: utf-8 -*-
"""Generate .docx and .pdf versions of the resume."""
import os
from docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, HRFlowable, Image, Table, TableStyle
from reportlab.lib import colors
OUT_DIR = r"C:\python\resume"
DOCX_PATH = os.path.join(OUT_DIR, "Резюме_Бойко_Кирилл_Сергеевич.docx")
PDF_PATH = os.path.join(OUT_DIR, "Резюме_Бойко_Кирилл_Сергеевич.pdf")
PHOTO_PATH = os.path.join(OUT_DIR, "dca7a868-65c0-422e-be26-06a5f2564cca.jfif")
ACCENT = RGBColor(0x1F, 0x4E, 0x79) # dark blue
ACCENT_HEX = "#1F4E79"
def build_docx():
doc = Document()
# Base style
style = doc.styles["Normal"]
style.font.name = "Calibri"
style.font.size = Pt(11)
# Margins
for section in doc.sections:
section.top_margin = Cm(2)
section.bottom_margin = Cm(2)
section.left_margin = Cm(2.2)
section.right_margin = Cm(2.2)
# Name + photo header
header = doc.add_table(rows=1, cols=2)
header.autofit = False
header.columns[0].width = Cm(13)
header.columns[1].width = Cm(4)
name_cell = header.cell(0, 0)
name_cell.vertical_alignment = 1 # center
name_p = name_cell.paragraphs[0]
name_p.alignment = WD_ALIGN_PARAGRAPH.LEFT
run = name_p.add_run("Бойко Кирилл Сергеевич")
run.bold = True
run.font.size = Pt(22)
run.font.color.rgb = ACCENT
photo_cell = header.cell(0, 1)
photo_cell.vertical_alignment = 1
photo_p = photo_cell.paragraphs[0]
photo_p.alignment = WD_ALIGN_PARAGRAPH.RIGHT
if os.path.exists(PHOTO_PATH):
photo_p.add_run().add_picture(PHOTO_PATH, width=Cm(3.6))
# Desired position removed
def heading(text):
p = doc.add_paragraph()
p.space_before = Pt(10)
run = p.add_run(text)
run.bold = True
run.font.size = Pt(14)
run.font.color.rgb = ACCENT
return p
def bullet(label, text):
p = doc.add_paragraph(style="List Bullet")
if label:
r = p.add_run(label + ": ")
r.bold = True
p.add_run(text)
return p
# Contact
heading("Контактная информация")
bullet("Дата рождения", "18.12.1989")
bullet("Адрес проживания", "ДНР, г. Донецк, пр. Театральный, 5")
bullet("Телефон", "+7 (949) 457-91-15")
bullet("E-mail", "kirill.b@itguild.info")
bullet("Telegram", "@kirill_bouko")
# About
heading("О себе")
about_p = doc.add_paragraph(
"Более 10 лет занимаюсь предпринимательской деятельностью в сфере ИТ. За это время "
"реализовал более 200 проектов — от разработки и внедрения информационных систем до "
"создания собственных цифровых продуктов полного цикла. В последние годы сосредоточен "
"на развитии и внедрении технологий искусственного интеллекта в информационные системы. "
"Совмещаю предпринимательство с активной общественной деятельностью: являюсь "
"Председателем Комитета «Информационных Технологий и Автоматизации Бизнеса» в ОО "
"«ОПОРА РОССИИ», Председателем Комитета по предпринимательству и экономической "
"грамотности молодежи Молодежного Парламента Донецкой Народной Республики, а также "
"Наставником проекта «Росмолодежь.Предпринимай». Сочетаю управленческие компетенции "
"(стратегия, управление проектами, бюджетирование, подбор персонала) с глубокими "
"техническими знаниями в области ИИ, машинного обучения и анализа данных."
)
for run in about_p.runs:
run.font.size = Pt(10)
# Key metrics
heading("Ключевые показатели")
doc.add_paragraph("10+ лет управленческого опыта в сфере ИТ", style="List Bullet")
doc.add_paragraph("200+ реализованных проектов", style="List Bullet")
doc.add_paragraph("15+ собственных цифровых продуктов, запущенных и развиваемых с нуля", style="List Bullet")
doc.add_paragraph("Полный цикл разработки: от идеи и проектирования до запуска и масштабирования", style="List Bullet")
doc.add_paragraph("Внедрение ИИ в информационные системы", style="List Bullet")
# Experience
heading("Опыт работы")
def job(title, period, site, desc):
p = doc.add_paragraph()
r = p.add_run(title)
r.bold = True
r.font.size = Pt(12)
p2 = doc.add_paragraph()
r2 = p2.add_run(period)
r2.italic = True
r2.font.color.rgb = RGBColor(0x60, 0x60, 0x60)
if site:
p3 = doc.add_paragraph()
r3 = p3.add_run(site)
r3.font.color.rgb = RGBColor(0x05, 0x63, 0xC1)
doc.add_paragraph(desc)
job("Соучредитель — Стартап ITGuild",
"июнь 2022 — настоящее время",
"https://itguild.info",
"Экосистема для диджитализации бизнеса, импортозамещающая ряд популярных сервисов. "
"Включает модули: система контроля версий (Git), канбан-доска, сервис видеосвязи, "
"система отчетности, размещение и отклик на вакансии, профиль IT-специалиста (навыки, "
"награды, фрагменты кода), встроенная CRM-система для управления IT-командой.")
job("Владелец — Интернет-портал для поиска работы Rabota Today",
"май 2019 — настоящее время",
"https://rabota.today",
"Сервис, облегчающий поиск и подбор специалистов различной квалификации. Предоставляет "
"соискателям возможность поиска по интересующим вакансиям. Имеет встроенный личный "
"кабинет (single page application) и функционал массового подбора.")
# Education
heading("Образование")
doc.add_paragraph(
"Донецкий Национальный Технический Университет, экономический факультет, кафедра "
"«Управления персоналом и Экономика труда», специальность «Управление персоналом и "
"экономика труда». Академическая степень — магистр."
)
doc.add_paragraph(
"Донецкий Национальный Технический Университет, экономический факультет, кафедра "
"хозяйственного права, специальность «Менеджмент организаций». Академическая степень — "
"бакалавр."
)
# Skills
heading("Навыки")
bullet("Управленческие", "стратегическое планирование, управление проектами, бюджетирование, поиск и подбор персонала")
bullet("Технические", "искусственный интеллект, машинное обучение, анализ данных, Python, C++, PHP, JavaScript, Linux, Git, MySQL, HTML, CSS")
# Tech competencies
heading("Ключевые технологические компетенции")
bullet("Основные языки и фреймворки", "PHP, Laravel, Symfony, Yii2; Python (Django, Flask, asyncio); JavaScript, Node.js, ES6, jQuery")
bullet("Базы данных", "MySQL, PostgreSQL, SQLite, Redis, PhpMyAdmin")
bullet("Инструменты и методологии", "Git, Docker, Composer, Nginx, RabbitMQ, Swagger; KISS, DRY, MVC")
# Additional
heading("Дополнительная информация")
doc.add_paragraph("Председатель Комитета по предпринимательству и экономической грамотности молодежи Молодежного Парламента Донецкой Народной Республики", style="List Bullet")
doc.add_paragraph("Председатель Комитета «Информационных Технологий и Автоматизации Бизнеса» в ОО «ОПОРА РОССИИ»", style="List Bullet")
doc.add_paragraph("Полуфиналист кадрового конкурса «Лидеры Возрождения. Донецкая Народная Республика»", style="List Bullet")
doc.add_paragraph("Прохожу обучение в «Школе 21»", style="List Bullet")
# Languages
heading("Языки")
bullet("Русский", "родной")
bullet("Украинский", "свободное владение")
doc.save(DOCX_PATH)
print("DOCX saved:", DOCX_PATH)
def build_pdf():
# Register Cyrillic-capable fonts (Helvetica does not support Cyrillic)
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont("DejaVuSans", r"C:\Windows\Fonts\DejaVuSans.ttf"))
pdfmetrics.registerFont(TTFont("DejaVuSans-Bold", r"C:\Windows\Fonts\DejaVuSans-Bold.ttf"))
pdfmetrics.registerFont(TTFont("DejaVuSans-Oblique", r"C:\Windows\Fonts\DejaVuSans-Oblique.ttf"))
pdfmetrics.registerFont(TTFont("DejaVuSans-BoldOblique", r"C:\Windows\Fonts\DejaVuSans-BoldOblique.ttf"))
pdfmetrics.registerFontFamily(
"DejaVuSans",
normal="DejaVuSans",
bold="DejaVuSans-Bold",
italic="DejaVuSans-Oblique",
boldItalic="DejaVuSans-BoldOblique",
)
styles = getSampleStyleSheet()
title_style = ParagraphStyle(
"TitleRU", parent=styles["Title"], fontName="DejaVuSans-Bold",
fontSize=22, leading=26, textColor=ACCENT_HEX, alignment=TA_CENTER, spaceAfter=4,
)
pos_style = ParagraphStyle(
"PosRU", parent=styles["Normal"], fontName="DejaVuSans-Bold",
fontSize=13, leading=16, textColor=ACCENT_HEX, alignment=TA_CENTER, spaceAfter=14,
)
heading_style = ParagraphStyle(
"HeadingRU", parent=styles["Heading1"], fontName="DejaVuSans-Bold",
fontSize=14, leading=18, textColor=ACCENT_HEX, spaceBefore=12, spaceAfter=4,
)
body_style = ParagraphStyle(
"BodyRU", parent=styles["Normal"], fontName="DejaVuSans",
fontSize=11, leading=15, spaceAfter=4,
)
about_style = ParagraphStyle(
"AboutRU", parent=body_style, fontSize=10, leading=13,
)
bullet_style = ParagraphStyle(
"BulletRU", parent=body_style, leftIndent=14, bulletIndent=4, spaceAfter=2,
)
job_style = ParagraphStyle(
"JobRU", parent=body_style, fontName="DejaVuSans-Bold", fontSize=12, leading=15, spaceBefore=6,
)
period_style = ParagraphStyle(
"PeriodRU", parent=body_style, fontName="DejaVuSans-Oblique",
fontSize=10, leading=13, textColor="#606060",
)
link_style = ParagraphStyle(
"LinkRU", parent=body_style, fontName="DejaVuSans", fontSize=10, leading=13,
textColor="#0563C1",
)
doc = SimpleDocTemplate(
PDF_PATH, pagesize=A4,
leftMargin=2.2 * cm, rightMargin=2.2 * cm,
topMargin=2 * cm, bottomMargin=2 * cm,
title="Резюме — Бойко Кирилл Сергеевич",
author="Бойко Кирилл Сергеевич",
)
story = []
# Name + photo header
name_para = Paragraph("Бойко Кирилл Сергеевич", title_style)
if os.path.exists(PHOTO_PATH):
img = Image(PHOTO_PATH, width=3.6 * cm, height=4.8 * cm)
img.hAlign = "RIGHT"
header_table = Table([[name_para, img]], colWidths=[13 * cm, 4 * cm])
header_table.setStyle(TableStyle([
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
("LEFTPADDING", (0, 0), (-1, -1), 0),
("RIGHTPADDING", (0, 0), (-1, -1), 0),
("TOPPADDING", (0, 0), (-1, -1), 0),
("BOTTOMPADDING", (0, 0), (-1, -1), 0),
]))
story.append(header_table)
else:
story.append(name_para)
story.append(HRFlowable(width="100%", thickness=1, color=ACCENT_HEX, spaceAfter=10))
def heading(text):
story.append(Paragraph(text, heading_style))
def bullet(label, text):
if label:
story.append(Paragraph(f"{label}: {text}", bullet_style))
else:
story.append(Paragraph(text, bullet_style))
heading("Контактная информация")
bullet("Дата рождения", "18.12.1989")
bullet("Адрес проживания", "ДНР, г. Донецк, пр. Театральный, 5")
bullet("Телефон", "+7 (949) 457-91-15")
bullet("E-mail", "kirill.b@itguild.info")
bullet("Telegram", "@kirill_bouko")
heading("О себе")
story.append(Paragraph(
"Более 10 лет занимаюсь предпринимательской деятельностью в сфере ИТ. За это время "
"реализовал более 200 проектов — от разработки и внедрения информационных систем до "
"создания собственных цифровых продуктов полного цикла. В последние годы сосредоточен "
"на развитии и внедрении технологий искусственного интеллекта в информационные системы. "
"Совмещаю предпринимательство с активной общественной деятельностью: являюсь "
"Председателем Комитета «Информационных Технологий и Автоматизации Бизнеса» в ОО "
"«ОПОРА РОССИИ», Председателем Комитета по предпринимательству и экономической "
"грамотности молодежи Молодежного Парламента Донецкой Народной Республики, а также "
"Наставником проекта «Росмолодежь.Предпринимай». Сочетаю управленческие компетенции "
"(стратегия, управление проектами, бюджетирование, подбор персонала) с глубокими "
"техническими знаниями в области ИИ, машинного обучения и анализа данных.",
about_style,
))
heading("Ключевые показатели")
bullet("", "10+ лет управленческого опыта в сфере ИТ")
bullet("", "200+ реализованных проектов")
bullet("", "15+ собственных цифровых продуктов, запущенных и развиваемых с нуля")
bullet("", "Полный цикл разработки: от идеи и проектирования до запуска и масштабирования")
bullet("", "Внедрение ИИ в информационные системы")
heading("Опыт работы")
def job(title, period, site, desc):
story.append(Paragraph(title, job_style))
story.append(Paragraph(period, period_style))
if site:
story.append(Paragraph(f'{site}', link_style))
story.append(Paragraph(desc, body_style))
job("Соучредитель — Стартап ITGuild",
"июнь 2022 — настоящее время",
"https://itguild.info",
"Экосистема для диджитализации бизнеса, импортозамещающая ряд популярных сервисов. "
"Включает модули: система контроля версий (Git), канбан-доска, сервис видеосвязи, "
"система отчетности, размещение и отклик на вакансии, профиль IT-специалиста (навыки, "
"награды, фрагменты кода), встроенная CRM-система для управления IT-командой.")
job("Владелец — Интернет-портал для поиска работы Rabota Today",
"май 2019 — настоящее время",
"https://rabota.today",
"Сервис, облегчающий поиск и подбор специалистов различной квалификации. Предоставляет "
"соискателям возможность поиска по интересующим вакансиям. Имеет встроенный личный "
"кабинет (single page application) и функционал массового подбора.")
heading("Образование")
story.append(Paragraph(
"Донецкий Национальный Технический Университет, экономический факультет, кафедра "
"«Управления персоналом и Экономика труда», специальность «Управление персоналом и "
"экономика труда». Академическая степень — магистр.",
body_style,
))
story.append(Paragraph(
"Донецкий Национальный Технический Университет, экономический факультет, кафедра "
"хозяйственного права, специальность «Менеджмент организаций». Академическая степень — "
"бакалавр.",
body_style,
))
heading("Навыки")
bullet("Управленческие", "стратегическое планирование, управление проектами, бюджетирование, поиск и подбор персонала")
bullet("Технические", "искусственный интеллект, машинное обучение, анализ данных, Python, C++, PHP, JavaScript, Linux, Git, MySQL, HTML, CSS")
heading("Ключевые технологические компетенции")
bullet("Основные языки и фреймворки", "PHP, Laravel, Symfony, Yii2; Python (Django, Flask, asyncio); JavaScript, Node.js, ES6, jQuery")
bullet("Базы данных", "MySQL, PostgreSQL, SQLite, Redis, PhpMyAdmin")
bullet("Инструменты и методологии", "Git, Docker, Composer, Nginx, RabbitMQ, Swagger; KISS, DRY, MVC")
heading("Дополнительная информация")
bullet("", "Председатель Комитета по предпринимательству и экономической грамотности молодежи Молодежного Парламента Донецкой Народной Республики")
bullet("", "Председатель Комитета «Информационных Технологий и Автоматизации Бизнеса» в ОО «ОПОРА РОССИИ»")
bullet("", "Полуфиналист кадрового конкурса «Лидеры Возрождения. Донецкая Народная Республика»")
bullet("", "Прохожу обучение в «Школе 21»")
heading("Языки")
bullet("Русский", "родной")
bullet("Украинский", "свободное владение")
doc.build(story)
print("PDF saved:", PDF_PATH)
if __name__ == "__main__":
build_docx()
build_pdf()