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', '
'), k_normal_style)) # 빌드 doc.build(elements) if __name__ == "__main__": if len(sys.argv) < 3: print("Usage: python pdf_report.py ") 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)