Guidelines

μ—‘μ…€ 데이터λ₯Ό 기반으둜 수료증 μŠ¬λΌμ΄λ“œ μƒμ„±ν•˜κΈ°

이번 μˆ˜μ—…μ—μ„œλŠ” 수료증 νŒŒμ›Œν¬μΈνŠΈ ν…œν”Œλ¦Ώ(.pptx)κ³Ό 학생 정보λ₯Ό 담은 μ—‘μ…€(.xlsx) νŒŒμΌμ„ 읽고, μ—‘μ…€μ—μ„œ κ°€μ Έμ˜¨ 데이터λ₯Ό λ°˜μ˜ν•œ μƒˆλ‘œμš΄ νŒŒμ›Œν¬μΈνŠΈ μŠ¬λΌμ΄λ“œλ₯Ό 생성해 λ³΄κ² μŠ΅λ‹ˆλ‹€.

μ°Έκ³  : μ»΄ν“¨ν„°μ—μ„œ μ‹€μŠ΅μœΌλ‘œ 제곡된 파이썬 ν”„λ‘œκ·Έλž¨μ„ 직접 μ‹€ν–‰ν•  경우, ν…œν”Œλ¦Ώ PPT(input_file.pptx)와 학생 정보(input_file.xlsx) 파일이 파이썬 ν”„λ‘œκ·Έλž¨κ³Ό λ™μΌν•œ 폴더 λ‚΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.


1. ν•„μˆ˜ 라이브러리 μž„ν¬νŠΈ

라이브러리 뢈러였기
import openpyxl from pptx import Presentation from io import BytesIO from pptx.enum.shapes import MSO_SHAPE_TYPE
  • io.BytesIO : μ»΄ν“¨ν„°μ˜ μ €μž₯ 곡간인 λ©”λͺ¨λ¦¬ 내에 λ°”μ΄νŠΈ 데이터(0κ³Ό 1둜 이루어진 데이터)λ₯Ό μ €μž₯ν•˜κ³ , 이λ₯Ό 파일처럼 μ‚¬μš©ν•  수 있게 ν•΄μ£ΌλŠ” ν΄λž˜μŠ€μž…λ‹ˆλ‹€.

  • pptx.enum.shapes.MSO_SHAPE_TYPE : νŒŒμ›Œν¬μΈνŠΈμ—μ„œ λ‹€μ–‘ν•œ λ„ν˜•μ˜ νƒ€μž…μ„ μ •μ˜ν•˜λŠ” μƒμˆ˜μž…λ‹ˆλ‹€. λ„ν˜•, 이미지, ν…μŠ€νŠΈ λ°•μŠ€ λ“±μ˜ νƒ€μž…μ„ ꡬ뢄할 λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.


2. νŒŒμ›Œν¬μΈνŠΈ 파일 및 μ—‘μ…€ 파일 λ‘œλ“œ

pptx, xlsx 파일 뢈러였기
presentation = Presentation("input_file.pptx") wb = openpyxl.load_workbook("input_file.xlsx") sheet = wb.active
  • Presentation("input_file.pptx") : νŒŒμ›Œν¬μΈνŠΈ νŒŒμΌμ„ λΆˆλŸ¬μ˜΅λ‹ˆλ‹€.

  • openpyxl.load_workbook("input_file.xlsx") : μ—‘μ…€ νŒŒμΌμ„ λΆˆλŸ¬μ˜΅λ‹ˆλ‹€.

  • wb.active : μ—‘μ…€ 파일의 첫 번째 μ‹œνŠΈλ₯Ό μ„ νƒν•©λ‹ˆλ‹€.


3. μ—‘μ…€ 데이터 읽기

data_sets 리슀트 생성
data_sets = [] for row in sheet.iter_rows(min_row=2, values_only=True): data = { "AWARD_NAME": row[0], "NAME": row[1], "CONTENT": row[2], "DATE": row[3], "ORGANIZATION": row[4], } data_sets.append(data)
  • sheet.iter_rows() : μ—‘μ…€ μ‹œνŠΈμ˜ 각 행을 λ°˜λ³΅ν•΄μ„œ μ½μ–΄μ˜΅λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” 2번째 ν–‰(min_row=2)λΆ€ν„° μ½μŠ΅λ‹ˆλ‹€.

  • values_only=True : μ…€μ˜ 값을 직접 κ°€μ Έμ˜΅λ‹ˆλ‹€.

  • data_sets.append(data) : 각 ν–‰μ˜ 데이터λ₯Ό dataλΌλŠ” λ”•μ…”λ„ˆλ¦¬λ‘œ μ €μž₯ν•˜κ³ , λ¦¬μŠ€νŠΈμ— μΆ”κ°€ν•©λ‹ˆλ‹€.


4. μŠ¬λΌμ΄λ“œ ν…œν”Œλ¦Ώ 선택

ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œ 선택
template_slide = presentation.slides[0]
  • presentation.slides[0] : νŒŒμ›Œν¬μΈνŠΈμ˜ 첫 번째 μŠ¬λΌμ΄λ“œλ₯Ό ν…œν”Œλ¦ΏμœΌλ‘œ μ„ νƒν•©λ‹ˆλ‹€. 이 μŠ¬λΌμ΄λ“œλ₯Ό λ°”νƒ•μœΌλ‘œ μƒˆ μŠ¬λΌμ΄λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

5. μŠ¬λΌμ΄λ“œ 볡사 및 이미지, ν…μŠ€νŠΈ 처리

μŠ¬λΌμ΄λ“œ μš”μ†Œ 볡사
for data in data_sets: # ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œλ₯Ό λ³΅μ‚¬ν•˜μ—¬ μƒˆλ‘œμš΄ μŠ¬λΌμ΄λ“œ 생성 new_slide = presentation.slides.add_slide(template_slide.slide_layout) for shape in template_slide.shapes: # κ·Έλ£Ή λ„ν˜• 처리 if shape.shape_type == MSO_SHAPE_TYPE.GROUP: for sub_shape in shape.shapes: if sub_shape.shape_type == MSO_SHAPE_TYPE.PICTURE: # ...μ€‘λž΅... # 이미지 λ„ν˜• 처리 elif shape.shape_type == MSO_SHAPE_TYPE.PICTURE: image_stream = shape.image.blob # ...μ€‘λž΅... # ν…μŠ€νŠΈ λ„ν˜• 처리 elif shape.has_text_frame: new_shape = new_slide.shapes.add_textbox(shape.left, shape.top, shape.width, shape.height) new_shape.text_frame.clear() # ν…μŠ€νŠΈ 볡사 for paragraph in shape.text_frame.paragraphs: new_paragraph = new_shape.text_frame.add_paragraph() # ...μ€‘λž΅...
  • presentation.slides.add_slide() : ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œλ₯Ό μ‚¬μš©ν•΄ μƒˆλ‘œμš΄ μŠ¬λΌμ΄λ“œλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

  • shape.shape_type == MSO_SHAPE_TYPE.GROUP : 그룹으둜 λ¬Άμ—¬ μžˆλŠ” λ„ν˜•μ„ μ²˜λ¦¬ν•  λ•Œ κ·Έλ£Ή λ‚΄λΆ€μ˜ λ„ν˜•λ“€μ„ λ”°λ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

  • shape.shape_type == MSO_SHAPE_TYPE.PICTURE : 이미지 λ„ν˜•μ„ μ²˜λ¦¬ν•  λ•Œ 이미지λ₯Ό μƒˆ μŠ¬λΌμ΄λ“œμ— λ³΅μ‚¬ν•©λ‹ˆλ‹€.

  • shape.has_text_frame : ν…μŠ€νŠΈκ°€ μžˆλŠ” λ„ν˜•μ„ 볡사할 λ•Œ, ν…μŠ€νŠΈ λ°•μŠ€λ₯Ό μƒˆλ‘œ λ§Œλ“€μ–΄μ„œ κ·Έ μ•ˆμ˜ ν…μŠ€νŠΈλ₯Ό λ³΅μ‚¬ν•©λ‹ˆλ‹€. ν…μŠ€νŠΈμ˜ 크기, κ΅΅κΈ°, κΈ°μšΈμž„λ„ μœ μ§€ν•©λ‹ˆλ‹€.


6. μ—‘μ…€ λ°μ΄ν„°λ‘œ ν…μŠ€νŠΈ λŒ€μ²΄

ν…μŠ€νŠΈ λ°μ΄ν„°λ‘œ λŒ€μ²΄
for shape in new_slide.shapes: if shape.has_text_frame: for paragraph in shape.text_frame.paragraphs: if "<AWARD_NAME>" in paragraph.text: paragraph.text = data["AWARD_NAME"] elif "<NAME>" in paragraph.text: paragraph.text = data["NAME"] elif "<CONTENT>" in paragraph.text: paragraph.text = data["CONTENT"] elif "<DATE>" in paragraph.text: paragraph.text = data["DATE"] elif "<ORGANIZATION>" in paragraph.text: paragraph.text = data["ORGANIZATION"]
  • μ—‘μ…€ 데이터(data)λ₯Ό νŒŒμ›Œν¬μΈνŠΈ μŠ¬λΌμ΄λ“œμ— μžˆλŠ” νŠΉμ • ν…μŠ€νŠΈμ™€ κ΅μ²΄ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, <AWARD_NAME>λΌλŠ” ν…μŠ€νŠΈλŠ” μ—‘μ…€μ—μ„œ 읽은 AWARD_NAME λ°μ΄ν„°λ‘œ λŒ€μ²΄λ©λ‹ˆλ‹€.

7. ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œ 제거 및 κ²°κ³Ό μ €μž₯

ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œ 제거 및 μ €μž₯
presentation.slides._sldIdLst.remove(presentation.slides._sldIdLst[0]) presentation.save("output_file.pptx")
  • _sldIdLst.remove() : 처음 μ‚¬μš©ν•œ ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œλ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.

  • presentation.save() : μ΅œμ’… κ²°κ³Όλ₯Ό output_file.pptx 파일둜 μ €μž₯ν•©λ‹ˆλ‹€.


전체적인 흐름 μš”μ•½

  1. μ—‘μ…€μ—μ„œ 데이터λ₯Ό μ½μ–΄μ˜΅λ‹ˆλ‹€.

  2. 첫 번째 μŠ¬λΌμ΄λ“œλ₯Ό ν…œν”Œλ¦ΏμœΌλ‘œ μ‚¬μš©ν•˜μ—¬ μ—‘μ…€μ˜ 각 데이터λ₯Ό μƒˆλ‘œμš΄ μŠ¬λΌμ΄λ“œμ— μ‚½μž…ν•©λ‹ˆλ‹€.

  3. ν…μŠ€νŠΈμ™€ 이미지λ₯Ό ν…œν”Œλ¦Ώκ³Ό λ™μΌν•˜κ²Œ λ³΅μ‚¬ν•˜λ©΄μ„œ, ν…μŠ€νŠΈ λ‚΄μš©μ€ μ—‘μ…€ λ°μ΄ν„°λ‘œ λŒ€μ²΄ν•©λ‹ˆλ‹€.

  4. ν…œν”Œλ¦Ώ μŠ¬λΌμ΄λ“œλ₯Ό μ‚­μ œν•˜κ³ , μ΅œμ’… κ²°κ³Όλ₯Ό 파일둜 μ €μž₯ν•©λ‹ˆλ‹€.


μœ„μ™€ 같이 μ—‘μ…€ νŒŒμΌμ—μ„œ 데이터λ₯Ό 읽어와, PPT ν…œν”Œλ¦Ώ λ‚΄ placeholderλ₯Ό λ°”κΎΈλ©΄ λ™μΌν•œ ν˜•μ‹μ˜ 수료증 μŠ¬λΌμ΄λ“œλ₯Ό μ—¬λŸ¬ 개 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ ꡬ쑰λ₯Ό 잘 μ‘μš©ν•˜λ©΄ λŒ€λŸ‰μ˜ 수료증, μΈμ¦μ„œ, λͺ…함 λ“± λ‹€μ–‘ν•œ ν…œν”Œλ¦Ώ 기반의 λ¬Έμ„œλ₯Ό μžλ™μœΌλ‘œ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.

Mission
0 / 1

Run the code and check the results.

Guidelines

AI Tutor

Publish

Design

Upload

Notes

Favorites

Help

Code Editor

Run
Generate

Execution Result

Input/Result

The document is empty.

Try running the code.