Skip to content

python-docx에서 마이그레이션

Office Oxide는 가장 흔한 python-docx 사용 사례 — 텍스트 추출, 단락 순회, 표 읽기, 찾기·바꾸기 — 의 그대로 교체용 라이브러리입니다. 속도는 14배, 2,538개 DOCX 코퍼스에서 통과율은 3.8%p 높습니다. 보너스로, .xlsx(openpyxl), .pptx(python-pptx), 레거시 .doc(catdoc / antiword)에 별도 라이브러리를 벤더링할 필요가 없어집니다 — pip install 한 번이 여섯 형식 모두를 커버합니다.

언제 마이그레이션할지

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

  • .docx에서 인제스트 / RAG / 검색용으로 텍스트나 Markdown을 추출
  • 수천 개의 문서에 찾기·바꾸기 기반 템플릿 실행
  • 계약서나 리포트에서 표 읽기
  • 의존성을 늘리지 않고 .xlsx, .pptx, 레거시 형식도 처리하고 싶음

다음을 하고 형식별 Rust API로 내려갈 준비가 안 됐다면 python-docx에 머무세요:

  • 커스텀 스타일과 테마로 처음부터 복잡한 DOCX 빌드
  • python-docx 확장 라이브러리(docxcompose, python-docx-ng 등)가 필요

설치

pip uninstall python-docx
pip install office-oxide

PyPI 배포 이름은 office-oxide(하이픈), 임포트는 office_oxide(언더스코어).

나란히 보는 치트시트

일반 텍스트

python-docx

from docx import Document

doc = Document("report.docx")
text = "\n".join(p.text for p in doc.paragraphs)

office_oxide

from office_oxide import Document

with Document.open("report.docx") as doc:
    text = doc.plain_text()

메서드 호출 한 번, 머리글/바닥글 포함, 약 14배 빠름.

Markdown / HTML

python-docx — 내장 Markdown / HTML 없음; pandoc, mammoth에 손을 뻗거나 변환기를 직접 작성해야 합니다.

office_oxide

from office_oxide import Document

with Document.open("report.docx") as doc:
    md   = doc.to_markdown()
    html = doc.to_html()

단락 순회

python-docx

from docx import Document

doc = Document("report.docx")
for p in doc.paragraphs:
    print(p.style.name, p.text)

office_oxide(IR 통해)

from office_oxide import Document

with Document.open("report.docx") as doc:
    ir = doc.to_ir()

for section in ir["sections"]:
    for el in section["elements"]:
        if el["kind"] == "Heading":
            print(f"H{el['level']}", el["text"])
        elif el["kind"] == "Paragraph":
            print("P", " ".join(r["text"] for r in el["runs"]))

표 순회

python-docx

from docx import Document

doc = Document("report.docx")
for table in doc.tables:
    for row in table.rows:
        cells = [cell.text for cell in row.cells]
        print(cells)

office_oxide

from office_oxide import Document

with Document.open("report.docx") 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-docx — 일급 API 없음; 흔한 패턴은 모든 런(run)을 순회하며 텍스트를 다시 쓰는 것이지만 런 경계를 가로지르는 매칭에서 깨집니다. 대부분 docx-mailmerge를 벤더링하거나 깨지기 쉬운 정규식을 작성합니다.

office_oxide

from office_oxide import EditableDocument

with EditableDocument.open("template.docx") as ed:
    n = ed.replace_text("{{client_name}}", "Acme Corp")
    print(f"{n}건 치환")
    ed.save("filled.docx")

replace_text는 런 경계를 가로지르는 매칭을 투명하게 처리하고 변경되지 않은 모든 OPC 파트(이미지, 차트, 스타일)를 보존합니다.

Core properties 읽기

python-docx

from docx import Document

doc = Document("report.docx")
print(doc.core_properties.author)
print(doc.core_properties.modified)

office_oxide

from office_oxide import Document

with Document.open("report.docx") as doc:
    props = doc.as_docx().core_properties()
    print(props.author)
    print(props.modified)

office_oxide가 현재 노출하지 않는 것

통합 EditableDocument가 템플레이팅 사례를 커버합니다. 더 풍부한 DOCX 구성 — 단락 추가, 프로그래밍적인 표 구축, 명명된 스타일 적용 — 을 위해서는 형식별 모듈로 들어가세요:

from office_oxide.docx import DocxBuilder

builder = DocxBuilder()
builder.add_heading("Q4 리포트", level=1)
builder.add_paragraph("매출이 18% 증가했습니다.")
builder.save("report.docx")

또는 IR에서 생성: create_from_ir(ir, "docx", "report.docx"). IR로 빌드 참고.

성능

같은 2,538개 코퍼스, 단일 스레드:

라이브러리 평균 p99 통과율
office_oxide 0.8 ms 3.9 ms 98.9%
python-docx 11.8 ms 98 ms 95.1%

100만 문서 인제스트가 python-docx에서는 3시간 16분, 같은 하드웨어에서 office_oxide는 14분에 끝냅니다.

더 보기