Files
report/backend/pdf_report.py
T
2026-07-19 03:44:35 +09:00

159 lines
5.2 KiB
Python

import sys
import json
import os
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm
# 한글 폰트 설정 (윈도우 기본 맑은 고딕 사용 시도)
def setup_font():
font_paths = [
"C:/Windows/Fonts/malgun.ttf",
"C:/Windows/Fonts/malgunsl.ttf",
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf" # For possible future Linux usage
]
selected_font = None
for path in font_paths:
if os.path.exists(path):
try:
font_name = 'KoreanFont'
pdfmetrics.registerFont(TTFont(font_name, path))
selected_font = font_name
break
except:
continue
return selected_font or 'Helvetica'
def generate_pdf(data, output_path):
FONT_NAME = setup_font()
styles = getSampleStyleSheet()
# 한글 지원 스타일 정의
k_title_style = ParagraphStyle(
'KTitle',
parent=styles['Title'],
fontName=FONT_NAME,
fontSize=24,
leading=30,
alignment=1, # Center
spaceAfter=30
)
k_header_style = ParagraphStyle(
'KHeader',
parent=styles['Heading2'],
fontName=FONT_NAME,
fontSize=14,
leading=18,
spaceBefore=20,
spaceAfter=10,
textColor=colors.hexColor("#2563eb")
)
k_normal_style = ParagraphStyle(
'KNormal',
parent=styles['Normal'],
fontName=FONT_NAME,
fontSize=10,
leading=14
)
doc = SimpleDocTemplate(
output_path,
pagesize=A4,
rightMargin=15*mm,
leftMargin=15*mm,
topMargin=20*mm,
bottomMargin=20*mm
)
elements = []
# 1. 상단 제목
company_name = data.get('name', '알 수 없음')
elements.append(Paragraph(f"{company_name} 사업분석 보고서", k_title_style))
# 2. 방문자 현황 섹션
elements.append(Paragraph("1. 방문자 현황", k_header_style))
visitor_table_data = data.get('visitorData', {}).get('table', [])
if visitor_table_data:
# 테이블 헤더
table_data = [['날짜', '방문자 수', '과거 대비']]
for row in visitor_table_data[:15]: # 상위 15개 데이터만 출력
table_data.append([
row.get('date', '-'),
str(row.get('value', '0')),
row.get('diff', '-') # Frontend에서 계산된 diff 값을 사용하거나 여기서 계산
])
t = Table(table_data, colWidths=[60*mm, 60*mm, 60*mm])
t.setStyle(TableStyle([
('FONTNAME', (0,0), (-1,-1), FONT_NAME),
('FONTSIZE', (0,0), (-1,-1), 9),
('BACKGROUND', (0,0), (-1,0), colors.hexColor("#f8fafc")),
('TEXTCOLOR', (0,0), (-1,0), colors.hexColor("#1e293b")),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('GRID', (0,0), (-1,-1), 0.5, colors.hexColor("#e2e8f0")),
('PADDING', (0,0), (-1,-1), 8)
]))
elements.append(t)
else:
elements.append(Paragraph("설정된 방문자 데이터가 없습니다.", k_normal_style))
# 3. 유입 경로 섹션
elements.append(Paragraph("2. 유입 경로 현황", k_header_style))
inflow_table_data = data.get('inflowData', {}).get('table', [])
if inflow_table_data:
table_data = [['유입 경로', '수치', '비중']]
for row in inflow_table_data:
table_data.append([
row.get('label', '-'),
str(row.get('value', '0')),
row.get('diff', '-')
])
t = Table(table_data, colWidths=[60*mm, 60*mm, 60*mm])
t.setStyle(TableStyle([
('FONTNAME', (0,0), (-1,-1), FONT_NAME),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('GRID', (0,0), (-1,-1), 0.5, colors.hexColor("#e2e8f0")),
('BACKGROUND', (0,0), (-1,0), colors.hexColor("#f8fafc")),
('PADDING', (0,0), (-1,-1), 8)
]))
elements.append(t)
else:
elements.append(Paragraph("설정된 유입 경로 데이터가 없습니다.", k_normal_style))
# 4. 다음 달 계획
elements.append(Paragraph("3. 향후 전략 및 계획", k_header_style))
plan_text = data.get('nextMonthPlan', '등록된 계획이 없습니다.')
elements.append(Paragraph(plan_text.replace('\n', '<br/>'), k_normal_style))
# 빌드
doc.build(elements)
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: python pdf_report.py <data_json_path> <output_pdf_path>")
sys.exit(1)
data_path = sys.argv[1]
output_path = sys.argv[2]
try:
with open(data_path, 'r', encoding='utf-8') as f:
report_data = json.load(f)
generate_pdf(report_data, output_path)
except Exception as e:
print(f"Error: {str(e)}")
sys.exit(1)