Files
InviteMe/app/services/excel_service.py
T
2026-08-28 12:28:52 +03:00

113 lines
4.1 KiB
Python

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