#!/usr/bin/env python3 # -*- coding: utf-8 -*- import pymysql import openpyxl from openpyxl.styles import PatternFill, Font from openpyxl.utils import get_column_letter from datetime import datetime timestamp = datetime.now().strftime("%Y-%m-%d %H-%M-%S") OUTPUT_PATH = fr"U:\Dropbox\!!!Days\Downloads Z230\{timestamp} medevio_patients_report.xlsx" # ============================ # CONFIGURATION # ============================ DB_CONFIG = { "host": "192.168.1.76", "port": 3307, "user": "root", "password": "Vlado9674+", "database": "medevio", "charset": "utf8mb4", "cursorclass": pymysql.cursors.DictCursor, } # ============================ # FUNCTIONS # ============================ from openpyxl.styles import Border, Side thin_border = Border( left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin') ) def apply_thin_borders(ws): """Apply thin borders to all cells in the worksheet.""" for row in ws.iter_rows(): for cell in row: cell.border = thin_border def autofit_columns(ws): """Auto-adjust column widths based on longest cell content.""" for col in ws.columns: max_length = 0 col_letter = get_column_letter(col[0].column) for cell in col: try: if cell.value: max_length = max(max_length, len(str(cell.value))) except: pass ws.column_dimensions[col_letter].width = max_length + 2 def apply_header_style(ws): """Make header BRIGHT YELLOW and bold.""" fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") font = Font(bold=True) for cell in ws[1]: cell.fill = fill cell.font = font def create_compact_row(row): """Produce compact record with merged pojistovna, with user_relationship after prijmeni.""" # insurance merged code = row.get("pojistovna_code") or "" naz = row.get("pojistovna_nazev") or "" if code and naz: poj = f"{code} ({naz})" elif code: poj = code elif naz: poj = naz else: poj = "" return { "id": row["id"], "jmeno": row["jmeno"], "prijmeni": row["prijmeni"], # 🔹 inserted here "user_relationship": row.get("user_relationship"), "rodne_cislo": row["rodne_cislo"], "dob": row["dob"], "telefon": row["telefon"], "email": row["email"], "pojistovna": poj, "status": row["status"], "has_mobile_app": row["has_mobile_app"], "registration_time": row["registration_time"], "last_update": row["last_update"], } def create_pozadavky_rows(rows): """Convert raw pozadavky SQL rows into rows for the Excel sheet.""" output = [] for r in rows: output.append({ # 🔹 First the ID "id": r["id"], # 🔹 Your 3 patient columns immediately after ID "pacient_jmeno": r["pacient_jmeno"], "pacient_prijmeni": r["pacient_prijmeni"], "pacient_rodnecislo": r["pacient_rodnecislo"], # 🔹 Then all other fields in any order you prefer "displayTitle": r["displayTitle"], "createdAt": r["createdAt"], "updatedAt": r["updatedAt"], "doneAt": r["doneAt"], "removedAt": r["removedAt"], "attachmentsProcessed": r["attachmentsProcessed"], "messagesProcessed": r["messagesProcessed"], "communicationprocessed": r["communicationprocessed"], "questionnaireprocessed": r["questionnaireprocessed"], "lastSync": r["lastSync"], }) return output # ============================ # MAIN # ============================ def main(): print("📥 Connecting to MySQL...") conn = pymysql.connect(**DB_CONFIG) with conn: with conn.cursor() as cur: cur.execute("SELECT * FROM medevio_pacienti ORDER BY prijmeni, jmeno") patients = cur.fetchall() print(f"📊 Loaded {len(patients)} patients.") # Load pozadavky with conn.cursor() as cur: cur.execute("SELECT * FROM pozadavky ORDER BY createdAt DESC") pozadavky_rows = cur.fetchall() print(f"📄 Loaded {len(pozadavky_rows)} pozadavky.") wb = openpyxl.Workbook() # --------------------------------- # 1) FULL SHEET # --------------------------------- ws_full = wb.active ws_full.title = "Patients FULL" if patients: headers = list(patients[0].keys()) ws_full.append(headers) for row in patients: ws_full.append([row.get(h) for h in headers]) apply_header_style(ws_full) ws_full.freeze_panes = "A2" ws_full.auto_filter.ref = ws_full.dimensions autofit_columns(ws_full) apply_thin_borders(ws_full) # --------------------------------- # 2) COMPACT SHEET # --------------------------------- ws_compact = wb.create_sheet("Patients COMPACT") compact_rows = [create_compact_row(r) for r in patients] compact_headers = list(compact_rows[0].keys()) ws_compact.append(compact_headers) for row in compact_rows: ws_compact.append([row.get(h) for h in compact_headers]) apply_header_style(ws_compact) ws_compact.freeze_panes = "A2" ws_compact.auto_filter.ref = ws_compact.dimensions autofit_columns(ws_compact) # >>> ADD THIS <<< ur_col_index = compact_headers.index("user_relationship") + 1 col_letter = get_column_letter(ur_col_index) ws_compact.column_dimensions[col_letter].width = 7.14 apply_thin_borders(ws_compact) # --------------------------------- # 3) POZADAVKY SHEET # --------------------------------- ws_p = wb.create_sheet("Pozadavky") poz_list = create_pozadavky_rows(pozadavky_rows) headers_p = list(poz_list[0].keys()) if poz_list else [] if headers_p: ws_p.append(headers_p) for row in poz_list: ws_p.append([row.get(h) for h in headers_p]) apply_header_style(ws_p) ws_p.freeze_panes = "A2" ws_p.auto_filter.ref = ws_p.dimensions autofit_columns(ws_p) apply_thin_borders(ws_p) # --------------------------------- # SAVE # --------------------------------- wb.save(OUTPUT_PATH) print(f"✅ Excel report saved to:\n{OUTPUT_PATH}") if __name__ == "__main__": main()