import fdb import openpyxl from openpyxl.styles import Font, PatternFill, Alignment from openpyxl.utils import get_column_letter from datetime import datetime import os import sys # --- Připojení --- conn = fdb.connect( dsn=r'localhost:c:\medicus 3\data\medicus.fdb', user='SYSDBA', password='masterkey', charset='win1250' ) cur = conn.cursor() # --- Výstupní soubor --- output_dir = r'u:\Dropbox\!!!Days\Downloads Z230' now = datetime.now() filename = now.strftime('%Y-%m-%d_%H-%M-%S') + '_Přehled posudků řidičák.xlsx' output_path = os.path.join(output_dir, filename) # --- Smazání předchozích verzí --- for f in os.listdir(output_dir): if f.endswith('_Přehled posudků řidičák.xlsx'): os.remove(os.path.join(output_dir, f)) wb = openpyxl.Workbook() # ===================== # Pomocné funkce # ===================== HEADER_FILL = PatternFill('solid', fgColor='2F5496') HEADER_FONT = Font(bold=True, color='FFFFFF') ZEBRA_FILL = PatternFill('solid', fgColor='DCE6F1') GREEN_FILL = PatternFill('solid', fgColor='C6EFCE') GREEN_FONT = Font(bold=True, color='276221') def style_header(ws): for cell in ws[1]: cell.fill = HEADER_FILL cell.font = HEADER_FONT cell.alignment = Alignment(horizontal='center') def autofit(ws): for col in ws.columns: max_len = max((len(str(cell.value)) if cell.value is not None else 0) for cell in col) ws.column_dimensions[get_column_letter(col[0].column)].width = min(max_len + 2, 50) def fmt(val): if val is None: return '' return val def parse_data(data_str): """Parsuje key=value text z HISTDOC.DATA do slovníku.""" result = {} if not data_str: return result for line in data_str.splitlines(): if '=' in line: key, _, val = line.partition('=') result[key.strip()] = val.strip() return result def parse_date(val): """Převede 'D:DD.MM.YYYY' na datetime.date, nebo vrátí původní hodnotu.""" if val and val.startswith('D:'): try: return datetime.strptime(val[2:], '%d.%m.%Y').date() except ValueError: return val return val # ===================== # List 1 – MOTORVO (ruční posudky k řízení) # ===================== ws1 = wb.active ws1.title = 'MOTORVO' # Množina (IDPACI, DATUM) kde existuje EPOSMRO cur.execute(""" SELECT IDPACI, DATUM FROM HISTDOC WHERE TYP = 'EPOSMRO' """) eposmro_keys = set((r[0], r[1]) for r in cur.fetchall()) cur.execute(""" SELECT h.ID, h.DATUM, h.IDPACI, k.PRIJMENI, k.JMENO, k.RODCIS, h.DATA, h.PORCISLO, h.STAV, h.PRINTED, h.IDUZIV, h.CREATED FROM HISTDOC h JOIN KAR k ON k.IDPAC = h.IDPACI WHERE h.TYP = 'MOTORVO' ORDER BY h.ID DESC """) raw_rows = cur.fetchall() headers = [ 'ID', 'DATUM', 'IDPACI', 'PRIJMENI', 'JMENO', 'RODCIS', 'PorCislo', 'DatumVyd', 'DatKonec', 'DruhProh', 'Posouzeni', 'ZpusobPodminka', 'SkupinaPodminka', 'Skupiny', 'ePosudek', 'STAV', 'PRINTED', 'IDUZIV', 'CREATED' ] ws1.append(headers) for i, row in enumerate(raw_rows, start=2): (hid, datum, idpac, prijmeni, jmeno, rodcis, data_blob, porcislo, stav, printed, iduziv, created) = row data = parse_data(data_blob) posouzeni = '' if data.get('Posouzeni') == 'T': if data.get('Posouzeni2') == 'T': posouzeni = 'nezpůsobilý' elif data.get('ZpusobPodminka') == 'B:1': posouzeni = 'způsobilý s podmínkou' else: posouzeni = 'způsobilý' skupiny = data.get('SkupinyRidicskehoOpravneniSeznam', '') if not skupiny: # MOTORVO nemá SkupinyRidicskehoOpravneniSeznam, zkusíme ZpusobJe skupiny = data.get('ZpusobJe', '') ws1.append([ hid, fmt(datum), idpac, fmt(prijmeni), fmt(jmeno), fmt(rodcis), fmt(porcislo or data.get('PorCislo', '')), parse_date(data.get('DatumVyd', '')), parse_date(data.get('DatKonec', '')), fmt(data.get('DruhProh', '')), posouzeni, fmt(data.get('ZpusobPodminka', '')), fmt(data.get('SkupinaPodminka', '')), fmt(skupiny), 'ANO' if (idpac, datum) in eposmro_keys else 'NE', fmt(stav), fmt(printed), fmt(iduziv), fmt(created), ]) if i % 2 == 0: for cell in ws1[i]: cell.fill = ZEBRA_FILL # Sloupec ePosudek – zvýraznit ANO zeleně epos_col = headers.index('ePosudek') + 1 cell = ws1.cell(row=i, column=epos_col) if cell.value == 'ANO': cell.fill = GREEN_FILL cell.font = GREEN_FONT style_header(ws1) ws1.freeze_panes = 'A2' autofit(ws1) # ===================== # List 2 – EPOSMRO (elektronická podání do registru) # ===================== ws2 = wb.create_sheet('EPOSMRO') cur.execute(""" SELECT h.ID, h.DATUM, h.IDPACI, k.PRIJMENI, k.JMENO, k.RODCIS, h.DATA, h.STAV, h.CREATED, e.ID_PODANI, e.ODESLANO, e.STATUS FROM HISTDOC h JOIN KAR k ON k.IDPAC = h.IDPACI LEFT JOIN HISTDOC_EPOSUDEK e ON e.ID_HISTDOC = h.ID WHERE h.TYP = 'EPOSMRO' ORDER BY h.ID DESC """) epos_rows = cur.fetchall() headers2 = [ 'ID', 'DATUM', 'IDPACI', 'PRIJMENI', 'JMENO', 'RODCIS', 'DatumVyd', 'DatKonec', 'DruhProhlidky', 'DruhPosudku', 'Vysledek', 'StavPosudku', 'TypAkce', 'STAV', 'CREATED', 'ID_PODANI', 'ODESLANO', 'STATUS_ODESL' ] ws2.append(headers2) for i, row in enumerate(epos_rows, start=2): (hid, datum, idpac, prijmeni, jmeno, rodcis, data_blob, stav, created, id_podani, odeslano, status_odesl) = row data = parse_data(data_blob) ws2.append([ hid, fmt(datum), idpac, fmt(prijmeni), fmt(jmeno), fmt(rodcis), parse_date(data.get('DatumVystaveni', '')), parse_date(data.get('PlatnostDo', '')), fmt(data.get('DruhProhlidkyNazev', '')), fmt(data.get('DruhPosudkuNazev', '')), fmt(data.get('VysledekNazev', '')), fmt(data.get('StavPosudkuNazev', '')), fmt(data.get('TypAkceNazev', '')), fmt(stav), fmt(created), fmt(id_podani), fmt(odeslano), fmt(status_odesl), ]) if i % 2 == 0: for cell in ws2[i]: cell.fill = ZEBRA_FILL style_header(ws2) ws2.freeze_panes = 'A2' autofit(ws2) # ===================== # Uložení # ===================== conn.close() wb.save(output_path) sys.stdout.buffer.write(f'Ulozeno: {output_path}\n'.encode('utf-8')) sys.stdout.buffer.write(f'MOTORVO: {len(raw_rows)} radku, EPOSMRO: {len(epos_rows)} radku\n'.encode('utf-8'))