#!/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 # ================== 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 ================== # Pozn.: CAST(ockzaz.datum AS DATE) pro přesné párování na lecd.datose (DATE). 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", /* --- VŠECHNY KÓDY Z TABULKY LECD PRO TOHO PACIENTA A TENTÝŽ DEN --- */ ( 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)", /* --- VŠECHNY KÓDY Z TABULKY vykonu dokladd PRO TOHO PACIENTA A TENTÝŽ DEN --- */ ( SELECT LIST(d.kod, ', ') FROM dokladd d WHERE d.rodcis = kar.rodcis AND d.datose = CAST(ockzaz.datum AS DATE) ) AS "Vykony (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 """ #and nazev containing 'chřipka' # ================== Načtení do DataFrame ================== df = pd.read_sql(sql, con) con.close() # Textové sloupce jako string 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") # Převod dat na datetime 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: df.to_excel(writer, index=False, sheet_name="Očkování") # ================== 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" ws_main = wb["Očkování"] style_table(ws_main, "Ockovani") format_dates(ws_main, ["Datum očkování", "Expirace"]) wb.save(xlsx_path) print(f"Hotovo. Uloženo do: {xlsx_path.resolve()}")