주간 방문객을 엑셀로 변환하는 코드, 정상 추출되지 않음

This commit is contained in:
2025-07-21 17:40:37 +09:00
parent 0114a81e8a
commit 52b7360f4a

View File

@ -0,0 +1,150 @@
import pandas as pd
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side
from openpyxl.chart import LineChart, Reference
from openpyxl.chart.series import SeriesLabel
from datetime import date
import os
def generate_excel_report(today, recent_dates, prev_year_dates, recent_data, prev_year_data, filename="visitor_report.xlsx"):
weekday_names = ['', '', '', '', '', '', '']
wb = Workbook()
ws = wb.active
ws.title = "방문자 리포트"
bold = Font(bold=True)
center = Alignment(horizontal='center', vertical='center')
thick_border = Border(
left=Side(style='thick'), right=Side(style='thick'),
top=Side(style='thick'), bottom=Side(style='thick')
)
def fmt(d):
return f"{d.month}{d.day}{weekday_names[d.weekday()]}"
headers = ["구분"] + [fmt(d) for d in recent_dates]
ws.append([])
for _ in range(23):
ws.append([])
data_start_row = 24
ws.append(headers)
# 범례 영역
ws.merge_cells(start_row=data_start_row, start_column=1, end_row=data_start_row + 6, end_column=1)
ws.merge_cells(start_row=data_start_row + 7, start_column=1, end_row=data_start_row + 13, end_column=1)
ws.cell(row=data_start_row, column=1, value=f"{today.year}").font = bold
ws.cell(row=data_start_row + 7, column=1, value=f"{today.year - 1}").font = bold
def row(label, key, data, suffix="", fmt_func=None):
r = [label]
for d in recent_dates:
v = data.get(d, {}).get(key, "")
if fmt_func:
v = fmt_func(v)
if v == 0 or v == '':
r.append("")
else:
r.append(f"{v}{suffix}")
return r
# 올해 예측 포함 입장객
merged_visitors = ["입장객수"]
for d in recent_dates:
actual = recent_data.get(d, {}).get("입장객 수", 0)
forecast = recent_data.get(d, {}).get("예상 방문자", None)
if d >= today and forecast:
merged_visitors.append(f"{actual} ({int(forecast)})")
else:
merged_visitors.append(actual if actual else "")
year_rows = [
row("홈페이지", "웹 방문자 수", recent_data),
merged_visitors,
row("최저기온", "최저기온", recent_data),
row("최고기온", "최고기온", recent_data),
row("습도", "습도", recent_data, "%"),
row("강수량", "강수량", recent_data),
row("미세먼지지수", "미세먼지", recent_data),
]
for r in year_rows:
ws.append(r)
# 작년 데이터
def prev_row(label, key, suffix="", fmt_func=None):
r = [label]
for d in prev_year_dates:
v = prev_year_data.get(d, {}).get(key, "")
if fmt_func:
v = fmt_func(v)
if v == 0 or v == '':
r.append("")
else:
r.append(f"{v}{suffix}")
return r
prev_rows = [
prev_row("홈페이지", "웹 방문자 수"),
prev_row("입장객수", "입장객 수"),
prev_row("최저기온", "최저기온"),
prev_row("최고기온", "최고기온"),
prev_row("습도", "습도", "%"),
prev_row("강수량", "강수량"),
prev_row("미세먼지지수", "미세먼지"),
]
for r in prev_rows:
ws.append(r)
# 증감 비교
diff = ["입장객 증감"]
rate = ["입장객 변동률"]
temp_dev = ["최고기온 편차"]
for i, d in enumerate(recent_dates):
cur = recent_data.get(d, {}).get("입장객 수", 0)
prev = prev_year_data.get(prev_year_dates[i], {}).get("입장객 수", 0)
if prev:
diff.append(cur - prev)
rate.append(f"{(cur - prev) / prev * 100:.1f}%")
else:
diff.append("")
rate.append("")
t1 = recent_data.get(d, {}).get("최고기온")
t2 = prev_year_data.get(prev_year_dates[i], {}).get("최고기온")
temp_dev.append(round(t1 - t2, 1) if t1 is not None and t2 is not None else "")
for row in [diff, rate, temp_dev]:
ws.append(row)
# 굵은 테두리 처리
for col, d in enumerate(recent_dates, start=2):
if d >= today:
for r in range(data_start_row + 1, data_start_row + 18):
ws.cell(row=r, column=col).border = thick_border
# 차트
chart = LineChart()
chart.title = "입장객 비교 (예상 포함 vs 작년)"
chart.height = 10
chart.width = 22
chart.y_axis.title = ""
chart.x_axis.title = "날짜"
label_ref = Reference(ws, min_col=2, min_row=data_start_row, max_col=1 + len(recent_dates))
this_year_ref = Reference(ws, min_col=2, min_row=data_start_row + 2, max_col=1 + len(recent_dates))
last_year_ref = Reference(ws, min_col=2, min_row=data_start_row + 9, max_col=1 + len(recent_dates))
chart.set_categories(label_ref)
chart.add_data(this_year_ref, titles_from_data=False)
chart.add_data(last_year_ref, titles_from_data=False)
chart.series[0].tx = SeriesLabel(v="입장객수 (예상 포함)")
chart.series[1].tx = SeriesLabel(v="작년 입장객수")
chart.series[1].graphicalProperties.solidFill = "999999"
ws.add_chart(chart, "A1")
wb.save(filename)
print(f"✅ 엑셀 저장 완료: {filename}")