Добавлены карточки с иконками в пункты 3 и 6 PDF
This commit is contained in:
parent
6e427512e2
commit
338eef8116
119
generate_pdf.py
119
generate_pdf.py
@ -139,6 +139,84 @@ class HotWeatherBriefingPDF(FPDF):
|
||||
def _measure_lines(self, w, line_h, text):
|
||||
return len(self.multi_cell(w, line_h, text, dry_run=True, output="LINES"))
|
||||
|
||||
def draw_card(self, emoji, title, text, x, y, w):
|
||||
"""Draw a single card with emoji, title and body text."""
|
||||
pad = 8
|
||||
# Calculate card height
|
||||
self.set_font("DejaVu", "B", 10)
|
||||
title_h = 6
|
||||
self.set_font("DejaVu", "", 9)
|
||||
n_lines = self._measure_lines(w - 2 * pad, 4.5, text)
|
||||
body_h = n_lines * 4.5 + 4
|
||||
card_h = pad + 12 + title_h + body_h + pad # emoji + title + body + padding
|
||||
|
||||
# Card background
|
||||
self.set_fill_color(*self.c["white"])
|
||||
self.set_draw_color(*self.c["gray_bg"])
|
||||
self.set_line_width(0.3)
|
||||
self.rect(x, y, w, card_h, "DF")
|
||||
|
||||
# Emoji
|
||||
self.set_xy(x + pad, y + pad)
|
||||
self.set_font("DejaVu", "", 20)
|
||||
self.cell(20, 12, emoji)
|
||||
|
||||
# Title
|
||||
self.set_xy(x + pad, y + pad + 12)
|
||||
self.set_font("DejaVu", "B", 10)
|
||||
self.set_text_color(*self.c["ink"])
|
||||
self.cell(w - 2 * pad, title_h, title)
|
||||
|
||||
# Body
|
||||
self.set_xy(x + pad, y + pad + 12 + title_h + 2)
|
||||
self.set_font("DejaVu", "", 9)
|
||||
self.set_text_color(*self.c["gray"])
|
||||
self.multi_cell(w - 2 * pad, 4.5, text, align="L")
|
||||
|
||||
return card_h
|
||||
|
||||
def draw_cards_row(self, cards, y, card_w=None):
|
||||
"""Draw 3 cards in a row. cards = list of (emoji, title, text)."""
|
||||
n = len(cards)
|
||||
gap = 12
|
||||
avail_w = self.w - self.l_margin - self.r_margin
|
||||
if card_w is None:
|
||||
card_w = (avail_w - gap * (n - 1)) / n
|
||||
for i, (emoji, title, text) in enumerate(cards):
|
||||
x = self.l_margin + i * (card_w + gap)
|
||||
self.draw_card(emoji, title, text, x, y, card_w)
|
||||
# Return max height
|
||||
max_h = 0
|
||||
for emoji, title, text in cards:
|
||||
pad = 8
|
||||
self.set_font("DejaVu", "", 9)
|
||||
n_lines = self._measure_lines(card_w - 2 * pad, 4.5, text)
|
||||
body_h = n_lines * 4.5 + 4
|
||||
card_h = pad + 12 + 6 + body_h + pad
|
||||
if card_h > max_h:
|
||||
max_h = card_h
|
||||
return max_h
|
||||
|
||||
def draw_cards_2x2(self, cards, y):
|
||||
"""Draw 4 cards in a 2x2 grid. cards = list of (emoji, title, text)."""
|
||||
gap = 12
|
||||
avail_w = self.w - self.l_margin - self.r_margin
|
||||
card_w = (avail_w - gap) / 2
|
||||
max_h = 0
|
||||
for row in range(2):
|
||||
for col in range(2):
|
||||
idx = row * 2 + col
|
||||
if idx < len(cards):
|
||||
emoji, title, text = cards[idx]
|
||||
x = self.l_margin + col * (card_w + gap)
|
||||
cy = y + row * (max_h + gap if max_h > 0 else 0)
|
||||
h = self.draw_card(emoji, title, text, x, cy, card_w)
|
||||
if row == 0 and col == 0:
|
||||
max_h = h
|
||||
elif h > max_h:
|
||||
max_h = h
|
||||
return max_h * 2 + gap
|
||||
|
||||
|
||||
def build():
|
||||
pdf = HotWeatherBriefingPDF()
|
||||
@ -213,7 +291,17 @@ def build():
|
||||
pdf.cell(col1_w, 7, " " + outdoor, border=1, fill=True)
|
||||
pdf.cell(col2_w, 7, " " + cabin, border=1, fill=True)
|
||||
pdf.cell(col3_w, 7, " " + risk, border=1, fill=True, new_x="LMARGIN", new_y="NEXT")
|
||||
pdf.ln(4)
|
||||
pdf.ln(6)
|
||||
|
||||
# Карточки рисков
|
||||
cards_risk = [
|
||||
("T", "Тепловой удар", "Потеря сознания, спутанность сознания, судороги. Риск ДТП \u2014 100%."),
|
||||
("\u2022", "Обезвоживание", "Снижение концентрации внимания, замедление реакции, головокружение."),
|
||||
("Z", "Гиперсомния", "Повышенная сонливость, \u00abмикрозасыпания\u00bb за рулём \u2014 основная причина лобовых столкновений."),
|
||||
]
|
||||
y_cards = pdf.get_y()
|
||||
cards_h = pdf.draw_cards_row(cards_risk, y_cards)
|
||||
pdf.set_y(y_cards + cards_h + 4)
|
||||
|
||||
# ══ 4. ДО ВЫЕЗДА НА ЛИНИЮ ══
|
||||
pdf.section_title("4. Действия до выезда на линию")
|
||||
@ -269,21 +357,20 @@ def build():
|
||||
|
||||
# ══ 6. ОСОБЫЕ ТРЕБОВАНИЯ ══
|
||||
pdf.section_title("6. Особые требования")
|
||||
pdf.sub_title("Режим работы в жару")
|
||||
pdf.body_text(
|
||||
"Выезд на линию — не ранее 6:00. Возвращение — не позднее 18:00. "
|
||||
"В период с 12:00 до 15:00 — обязательный перерыв в тенистом месте (не менее 30 минут)."
|
||||
)
|
||||
pdf.sub_title("Запреты")
|
||||
pdf.body_text(
|
||||
"Запрещается: оставлять детей в ТС, оставлять ТС с работающим двигателем "
|
||||
"без присмотра, перевозить легковоспламеняющиеся жидкости без охлаждения."
|
||||
)
|
||||
pdf.sub_title("Взаимный контроль")
|
||||
pdf.body_text(
|
||||
"Водители обязаны проверять состояние здоровья коллег при встрече. "
|
||||
"При признаках недомогания у коллеги — оказать помощь и сообщить диспетчеру."
|
||||
)
|
||||
|
||||
cards_special = [
|
||||
("\u25b6", "Режим работы в жару",
|
||||
"Выезд на линию \u2014 не ранее 6:00. Возвращение \u2014 не позднее 18:00. В период с 12:00 до 15:00 \u2014 обязательный перерыв в тенистом месте (не менее 30 минут)."),
|
||||
("\u2716", "Запреты",
|
||||
"Запрещается: оставлять детей в ТС, оставлять ТС с работающим двигателем без присмотра, перевозить легковоспламеняющиеся жидкости без охлаждения."),
|
||||
("\u25cb", "Охлаждение",
|
||||
"Допускается использование portative вентиляторов от прикуривателя, охлаждающих бандажей, бутылок с замороженной водой."),
|
||||
("\u25a1", "Взаимный контроль",
|
||||
"Водители обязаны проверять состояние здоровья коллег при встрече. При признаках недомогания у коллеги \u2014 оказать помощь и сообщить диспетчеру."),
|
||||
]
|
||||
y_cards6 = pdf.get_y()
|
||||
cards_h6 = pdf.draw_cards_2x2(cards_special, y_cards6)
|
||||
pdf.set_y(y_cards6 + cards_h6 + 4)
|
||||
|
||||
# ══ 7. ЧЕК-ЛИСТ ══
|
||||
pdf.section_title("7. Чек-лист перед выездом")
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user