Skip to content

python-pptx에서 마이그레이션

Office Oxide는 python-pptx보다 PPTX를 46배 빠르게 읽습니다(806개 파일 평균 0.7 ms 대 32.5 ms). 통과율은 11.7%p 더 높고, 레거시 .ppt도 직접 읽습니다 — python-pptx는 할 수 없습니다.

언제 마이그레이션할까

다음 중 하나라도 한다면 전환하세요:

  • .pptx에서 슬라이드 텍스트, 노트, 테이블을 인제스트 / RAG용으로 추출
  • 미리보기용으로 덱을 Markdown이나 HTML로 변환
  • 찾기·바꾸기 템플릿화(“Q3 → Q4”, “{{quarter}}”, “{{growth}}”) 실행
  • LibreOffice 셸아웃 없이 .ppt 지원 필요
  • .docx, .xlsx, 레거시 포맷까지 커버하는 단일 라이브러리 원함

python-pptx에 남는 게 나은 경우:

  • 커스텀 레이아웃, 애니메이션, 전환, 도형 지오메트리를 갖춘 복잡한 PPTX를 처음부터 구축
  • 슬라이드 레이아웃 XML에 대한 세밀한 제어 필요

설치

pip uninstall python-pptx
pip install office-oxide

비교 치트시트

모든 슬라이드 텍스트 읽기

python-pptx

from pptx import Presentation

prs = Presentation("deck.pptx")
for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_text_frame:
            for para in shape.text_frame.paragraphs:
                for run in para.runs:
                    print(run.text)

office_oxide

from office_oxide import Document

with Document.open("deck.pptx") as doc:
    text = doc.plain_text()
print(text)

슬라이드 단위 순회

python-pptx

prs = Presentation("deck.pptx")
for i, slide in enumerate(prs.slides, 1):
    title = slide.shapes.title.text if slide.shapes.title else "(no title)"
    print(f"slide {i}: {title}")

office_oxide

with Document.open("deck.pptx") as doc:
    ir = doc.to_ir()

for i, section in enumerate(ir["sections"], 1):
    print(f"slide {i}: {section.get('title') or '(no title)'}")

각 IR 섹션은 슬라이드 한 장에 대응합니다. section["title"]은 제목 자리표시자에서 옵니다.

슬라이드의 테이블 읽기

python-pptx

for slide in prs.slides:
    for shape in slide.shapes:
        if shape.has_table:
            for row in shape.table.rows:
                cells = [c.text for c in row.cells]
                print(cells)

office_oxide

with Document.open("deck.pptx") as doc:
    ir = doc.to_ir()

for section in ir["sections"]:
    for el in section["elements"]:
        if el["kind"] == "Table":
            for row in el["rows"]:
                print(row)

발표자 노트 읽기

python-pptx

for slide in prs.slides:
    if slide.has_notes_slide:
        print(slide.notes_slide.notes_text_frame.text)

office_oxide

plain_text()to_markdown()은 기본적으로 노트를 포함합니다 — 각 슬라이드 섹션 끝에 덧붙여집니다. 노트를 따로 가져와야 하면 포맷별 접근자를 사용하세요:

with Document.open("deck.pptx") as doc:
    pptx = doc.as_pptx()
    for i, slide in enumerate(pptx.slides(), 1):
        notes = slide.notes()
        if notes:
            print(f"slide {i} notes: {notes}")

템플릿화(찾기·바꾸기)

python-pptx — 일급 API 없음. 흔한 패턴은 모든 도형의 텍스트 프레임을 순회하며 다시 쓰는 것입니다. 런(run) 경계에서 깨지기 쉽습니다.

office_oxide

from office_oxide import EditableDocument

with EditableDocument.open("deck_template.pptx") as ed:
    ed.replace_text("{{quarter}}", "Q4 2026")
    ed.replace_text("{{growth}}",  "+18.4%")
    ed.save("q4_deck.pptx")

replace_text는 모든 슬라이드와 노트 슬라이드의 모든 <a:t>를 순회하며, 수정되지 않은 OPC 파트(이미지, 차트, 레이아웃, 테마)는 그대로 보존합니다.

Markdown / HTML로 변환

python-pptx — 내장 없음.

office_oxide

with Document.open("deck.pptx") as doc:
    md   = doc.to_markdown()
    html = doc.to_html()

Markdown 출력은 슬라이드당 ## Slide N 섹션 하나로, 본문 내용이 이어지고 노트는 인용구로 덧붙습니다.

레거시 .ppt 읽기

python-pptx는 .ppt를 열 수 없습니다. Office Oxide는 바로 읽습니다:

from office_oxide import Document

with Document.open("legacy.ppt") as doc:
    print(doc.plain_text())
    doc.save_as("modern.pptx")    # 한 줄 마이그레이션

성능

라이브러리 평균 p99 통과율
office_oxide 0.7 ms 3.9 ms 98.4%
python-pptx 32.5 ms 174 ms 86.7%

python-pptx로 54분 걸리는 10만 덱 인제스트가 office_oxide로는 70초에 끝납니다.

잃는 것

EditableDocument는 템플릿화 사용 사례를 커버합니다. 슬라이드 추가, 커스텀 레이아웃, 차트, 애니메이션 등 더 풍부한 PPTX 구축에는 office_oxide.pptx::create::PptxBuilder로 내려가거나, 생성 단계는 python-pptx에 두고 인제스트는 office_oxide로 처리하세요.

관련 항목