from pathlib import Path from openpyxl import load_workbook, Workbook from openpyxl.styles import Font, PatternFill, Alignment from app import db from app.models import Guest REQUIRED_COLUMNS = ["Отдел", "ФИО", "Должность", "e-mail", "название фото"] def read_guests_from_excel(file_path): """Читает список гостей из Excel-файла.""" file_path = Path(file_path) wb = load_workbook(file_path, data_only=True) ws = wb.active # Определяем заголовки headers = [str(cell.value).strip() if cell.value else "" for cell in ws[1]] missing = [col for col in REQUIRED_COLUMNS if col not in headers] if missing: raise ValueError(f"В файле отсутствуют обязательные столбцы: {', '.join(missing)}") col_indices = {col: headers.index(col) for col in REQUIRED_COLUMNS} guests_data = [] for row in ws.iter_rows(min_row=2, values_only=True): full_name = str(row[col_indices["ФИО"]]).strip() if row[col_indices["ФИО"]] else "" email = str(row[col_indices["e-mail"]]).strip() if row[col_indices["e-mail"]] else "" if not full_name or not email: continue guests_data.append({ "department": str(row[col_indices["Отдел"]]).strip() if row[col_indices["Отдел"]] else "", "full_name": full_name, "position": str(row[col_indices["Должность"]]).strip() if row[col_indices["Должность"]] else "", "email": email, "photo_filename": str(row[col_indices["название фото"]]).strip() if row[col_indices["название фото"]] else "", }) return guests_data def import_guests_from_excel(file_path): """Импортирует гостей из Excel в базу данных.""" guests_data = read_guests_from_excel(file_path) imported = 0 updated = 0 for data in guests_data: guest = Guest.query.filter_by(email=data["email"]).first() if guest: guest.department = data["department"] guest.full_name = data["full_name"] guest.position = data["position"] guest.photo_filename = data["photo_filename"] guest.is_active = True updated += 1 else: guest = Guest(**data) db.session.add(guest) imported += 1 db.session.commit() return {"imported": imported, "updated": updated, "total": len(guests_data)} def export_report_to_excel(output_path, event_name="Корпоратив"): """Выгружает отчёт о посещаемости в Excel.""" guests = Guest.query.order_by(Guest.department, Guest.full_name).all() wb = Workbook() ws = wb.active ws.title = "Отчёт" headers = ["Отдел", "ФИО", "Должность", "Email", "Название фото", "Статус", "Время входа"] ws.append(headers) # Стили заголовков for cell in ws[1]: cell.font = Font(bold=True) cell.fill = PatternFill(start_color="DDDDDD", end_color="DDDDDD", fill_type="solid") cell.alignment = Alignment(horizontal="center") for guest in guests: status = "Пришёл" if guest.is_checked_in else "Не пришёл" check_in_time = guest.last_check_in.strftime("%d.%m.%Y %H:%M:%S") if guest.last_check_in else "" ws.append([ guest.department, guest.full_name, guest.position or "", guest.email, guest.photo_filename or "", status, check_in_time, ]) # Автоширина колонок for column in ws.columns: max_length = 0 column_letter = column[0].column_letter for cell in column: try: if cell.value: max_length = max(max_length, len(str(cell.value))) except Exception: pass ws.column_dimensions[column_letter].width = min(max_length + 2, 50) wb.save(output_path) return output_path