728x90
반응형
>> 저장될 때 파일명에 학생 이름과 작성월이 포함되게
>> 코드에서 추출한 아이디 정보로 학생 아이디 목록 엑셀 파일에 접근해서 학생이름 찾기, 월은 작성하는 날의 정보에서
from PIL import Image, ImageDraw, ImageFont
import pandas as pd
from datetime import datetime
# 파일 경로 설정
template_path = "C:/Users/MJ/Desktop/월간리포트만들기/template.png" # 템플릿 이미지
grade_graph_path = "C:/Users/MJ/Desktop/월간리포트만들기/cg.png" # 성적 그래프
progress_graph_path = "C:/Users/MJ/Desktop/월간리포트만들기/cp.png" # 진도 그래프
font_path = "C:/Users/MJ/Desktop/월간리포트만들기/NanumGothic.ttf" # 한글 폰트
excel_path = "C:/Users/MJ/Desktop/월간리포트만들기/StudentName.xlsx" # 엑셀 파일 경로
# 엑셀 파일에서 학생 이름 찾기
try:
df = pd.read_excel(excel_path)
print("엑셀 파일 로드 완료:")
print(df) # 엑셀 파일 내용 확인
except Exception as e:
print(f"엑셀 파일 로드 실패: {e}")
exit()
# 'cg.png'에서 'c' 추출 (student_id)
student_id = grade_graph_path.split('/')[-1][0] # 'c' 추출
print(f"추출된 student_id: {student_id}") # 디버깅 메시지
# student_id와 엑셀 파일의 id 열 데이터 타입 일치시키기
df['id'] = df['id'].astype(str).str.strip() # id 열을 문자열로 변환하고 공백 제거
student_id = str(student_id).strip() # student_id도 문자열로 변환하고 공백 제거
# 학생 이름 찾기
try:
student_name = df.loc[df['id'] == student_id, 'student_name'].values[0]
print(f"찾은 student_name: {student_name}") # 디버깅 메시지
except IndexError:
print(f"⚠️ 오류: student_id '{student_id}'에 해당하는 학생 이름을 찾을 수 없습니다.")
exit()
# 템플릿 및 그래프 이미지 로드
template = Image.open(template_path)
grade_graph = Image.open(grade_graph_path)
progress_graph = Image.open(progress_graph_path)
# 텍스트 피드백 준비 (수동 입력)
feedback_text = """코딩을 잘하려면 기본 개념을 탄탄히 이해하고 꾸준히 연습하며, 알고리즘 문제나 작은 프로젝트를 통해 실력을 키우고, 다른 사람의 코드를 리뷰하거나 공식 문서를 읽으며 배우고, 에러를 해결하는 디버깅 능력을 기르고, 새로운 기술을 꾸준히 학습하며 개발자 커뮤니티에 참여해 정보를 공유하고, 실제로 동작하는 프로젝트를 진행해보는 것이 중요합니다.
"""
# 텍스트 박스 설정
text_box_x = 226
text_box_y = 5334
text_box_width = 4156 # 텍스트 박스 폭
text_box_height = 1021 # 텍스트 박스 높이
# 폰트 크기 및 줄 간격 설정
font_size = 100
min_font_size = 50
max_font_size = 120
line_spacing = 20
max_iterations = 100 # 무한 루프 방지
iteration = 0
# 텍스트 크기 조정 루프
while iteration < max_iterations:
iteration += 1 # 반복 횟수 증가
font = ImageFont.truetype(font_path, font_size)
wrapped_text = []
current_line = ""
for word in feedback_text.split():
test_line = f"{current_line} {word}".strip()
bbox = font.getbbox(test_line)
text_width = bbox[2] - bbox[0]
if text_width <= text_box_width:
current_line = test_line
else:
wrapped_text.append(current_line)
current_line = word
wrapped_text.append(current_line)
# 전체 텍스트 높이 계산
total_height = sum(font.getbbox(line)[3] - font.getbbox(line)[1] + line_spacing for line in wrapped_text) - line_spacing
# 텍스트 크기 조정
if total_height > text_box_height:
font_size -= 2
line_spacing = max(10, line_spacing - 1)
elif total_height < text_box_height * 0.9:
font_size += 2
line_spacing += 1
else:
break # 박스에 적절히 맞으면 종료
# 최소 글자 크기 제한
if font_size < min_font_size:
print("⚠️ 글자 크기가 너무 작아졌습니다. 텍스트 크기 조정을 중단합니다.")
font_size = min_font_size
break
# 디버깅 메시지 출력
print(f"Iteration {iteration}: Font Size = {font_size}, Line Spacing = {line_spacing}")
# 루프 종료 확인
if iteration == max_iterations:
print("🚨 경고: 최대 반복 횟수를 초과하여 루프를 종료합니다.")
print("✅ 최종 텍스트 배치 완료")
# 텍스트 삽입
draw = ImageDraw.Draw(template)
y_position = text_box_y
for line in wrapped_text:
draw.text((text_box_x, y_position), line, font=font, fill="black")
y_position += font.getbbox(line)[3] - font.getbbox(line)[1] + line_spacing
# 그래프 크기 및 위치 설정
grade_graph = grade_graph.resize((4234, 2142))
progress_graph = progress_graph.resize((4270, 1356))
template.paste(grade_graph, (196, 992))
template.paste(progress_graph, (178, 3511))
# PDF 저장 경로 생성
current_month = datetime.now().month
pdf_path = f"C:/Users/MJ/Desktop/월간리포트만들기/MonthlyReport_{student_name}_{current_month}월.pdf"
# PDF로 저장
template.save(pdf_path, "PDF", resolution=200.0)
print(f"🎉 성적표 PDF가 성공적으로 생성되었습니다: {pdf_path}")
>> 결과
728x90
반응형