#!/usr/bin/env python3 # -*- coding: utf-8 -*- from pathlib import Path import time import fdb import pandas as pd from openpyxl import load_workbook from openpyxl.worksheet.table import Table, TableStyleInfo from openpyxl.styles import Font, PatternFill, Alignment from openpyxl.utils import get_column_letter import re # map "Látka" names to sheet names sheet_mapping = { "Chřipka": ["Influvac", "Vaxigrip", "Fluarix"], "HepA": ["Avaxim", "Havrix"], "HepB": ["Engerix"], "HepA+B": ["Twinrix"], "COVID": ["Comirnaty"], "Klíšťovka": ["FSME"] } # ================== Výstupní cesta ================== BASE_DIR = Path(r"..") # uprav dle potřeby timestamp = time.strftime("%Y-%m-%d %H-%M-%S") xlsx_name = f"Pacienti očkování {timestamp}.xlsx" xlsx_path = BASE_DIR / xlsx_name # ================== Připojení k DB ================== con = fdb.connect( host='192.168.1.4', database=r'z:\\MEDICUS 3\\data\\medicus.FDB', user='sysdba', password='masterkey', charset='WIN1250' ) # ================== SQL dotaz ================== sql = """ SELECT kar.rodcis AS "Rodné číslo", kar.prijmeni AS "Příjmení", kar.jmeno AS "Jméno", ockzaz.datum AS "Datum očkování", ockzaz.kodmz AS "Kód MZ", ockzaz.poznamka AS "Šarže", ockzaz.latka AS "Látka", ockzaz.nazev AS "Název", ockzaz.expire AS "Expirace", ( SELECT LIST(l.kod, ', ') FROM lecd l WHERE l.rodcis = kar.rodcis AND l.datose = CAST(ockzaz.datum AS DATE) ) AS "LECD kódy (ten den)", ( SELECT LIST(d.kod, ', ') FROM dokladd d WHERE d.rodcis = kar.rodcis AND d.datose = CAST(ockzaz.datum AS DATE) ) AS "Výkony (ten den)" FROM registr JOIN kar ON registr.idpac = kar.idpac JOIN ockzaz ON registr.idpac = ockzaz.idpac WHERE registr.datum_zruseni IS NULL AND kar.vyrazen <> 'A' AND kar.rodcis IS NOT NULL AND idicp <> 0 AND EXTRACT(YEAR FROM ockzaz.datum)=2025 ORDER BY ockzaz.datum DESC """ # ================== Načtení do DataFrame ================== df = pd.read_sql(sql, con) con.close() # Typy sloupců for col in ["Kód MZ", "Šarže", "Rodné číslo", "Látka", "Název", "Příjmení", "Jméno", "LECD kódy","Výkony"]: if col in df.columns: df[col] = df[col].astype("string") for dcol in ["Datum očkování", "Expirace"]: if dcol in df.columns: df[dcol] = pd.to_datetime(df[dcol], errors="coerce") # ================== Uložení do Excelu ================== with pd.ExcelWriter(xlsx_path, engine="openpyxl") as writer: # --- 1️⃣ Custom groups --- for sheet_name, latky in sheet_mapping.items(): mask = df["Látka"].isin(latky) subdf = df[mask] if not subdf.empty: safe_name = re.sub(r'[\\/*?:[\]]', '', str(sheet_name))[:31] subdf.to_excel(writer, index=False, sheet_name=safe_name) # # --- 2️⃣ Optionally add sheet for "ostatní" --- # used_latky = {l for group in sheet_mapping.values() for l in group} # remaining = df[~df["Látka"].isin(used_latky)] # if not remaining.empty: # remaining.to_excel(writer, index=False, sheet_name="Ostatní") # ================== Formátování ================== wb = load_workbook(xlsx_path) def autosize_columns(ws): for col_idx in range(1, ws.max_column + 1): col_letter = get_column_letter(col_idx) max_len = 0 for cell in ws[col_letter]: val = "" if cell.value is None else str(cell.value) if len(val) > max_len: max_len = len(val) ws.column_dimensions[col_letter].width = min(max(12, max_len + 2), 60) def style_table(ws, table_name: str): max_row = ws.max_row max_col = ws.max_column if max_col == 0: return # Hlavička vzhled header_fill = PatternFill("solid", fgColor="D9E1F2") for cell in ws[1]: cell.font = Font(bold=True) cell.fill = header_fill cell.alignment = Alignment(vertical="center") # Freeze top row ws.freeze_panes = "A2" # Tabulka jen pokud jsou data if max_row < 2: autosize_columns(ws) return ref = f"A1:{get_column_letter(max_col)}{max_row}" tbl = Table(displayName=table_name, ref=ref) tbl.tableStyleInfo = TableStyleInfo( name="TableStyleMedium9", showRowStripes=True, showColumnStripes=False ) ws.add_table(tbl) autosize_columns(ws) def format_dates(ws, columns_names): header = [c.value for c in ws[1]] date_cols = [header.index(name) + 1 for name in columns_names if name in header] for col_idx in date_cols: for row in ws.iter_rows(min_row=2, min_col=col_idx, max_col=col_idx, max_row=ws.max_row): row[0].number_format = "DD.MM.YYYY" # Formátuj všechny listy for ws in wb.worksheets: table_name = re.sub(r'\W+', '_', ws.title)[:30] or "Tabulka" style_table(ws, table_name) format_dates(ws, ["Datum očkování", "Expirace"]) wb.save(xlsx_path) print(f"Hotovo. Uloženo do: {xlsx_path.resolve()}")