Skip to content

Python Office 라이브러리 — 빠른 시작

office_oxide는 Office 문서 처리 분야에서 가장 빠른 Python 라이브러리입니다. 순수 Rust 코어, Python다운 API, 의존성 없음. DOCX, XLSX, PPTX(및 레거시 DOC, XLS, PPT)를 1밀리초 미만에 읽습니다 — python-docx, openpyxl, python-pptx보다 8~100배 빠릅니다.

설치

pip install office-oxide

CPython 3.8~3.14를 위한 wheel이 Linux, macOS, Windows용으로 배포됩니다. PyPI 패키지 이름은 office-oxide(하이픈), 임포트 이름은 office_oxide(언더스코어)입니다.

문서 읽기

from office_oxide import Document

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

한 줄 호출 형태도 사용할 수 있습니다:

import office_oxide
print(office_oxide.extract_text("report.docx"))

핵심 API

Document.open은 파일 확장자에서 형식을 감지하고(매직 바이트로 다시 검증), str, bytes, os.PathLike를 받습니다. 컨텍스트 매니저로 사용하면 네이티브 메모리가 결정적으로 해제됩니다.

from pathlib import Path
from office_oxide import Document

with Document.open(Path("data/deck.pptx")) as doc:
    print(doc.format)           # "pptx"
    print(doc.plain_text())     # str
    print(doc.to_markdown())    # str — GitHub Flavored Markdown
    print(doc.to_html())        # str — 시맨틱 HTML
    ir = doc.to_ir()            # 중첩 dict (DocumentIR)

    doc.save_as("deck.docx")    # 레거시 PPT → PPTX도 가능

파일이 디스크에 없을 때 원시 바이트에서 열기:

data = open("report.xlsx", "rb").read()
with Document.from_bytes(data, "xlsx") as doc:
    print(doc.plain_text())

모듈 레벨 단축 함수:

import office_oxide
office_oxide.extract_text("file.docx")   # → str
office_oxide.to_markdown("file.pptx")    # → str
office_oxide.to_html("file.xlsx")        # → str
office_oxide.version()                   # → "0.1.0"

편집

EditableDocument는 변경되지 않은 OPC 파트(이미지, 차트, 스타일, 관계)를 저장 시 그대로 보존합니다. DOCX, XLSX, PPTX만 지원합니다.

from office_oxide import EditableDocument

with EditableDocument.open("template.docx") as ed:
    n = ed.replace_text("{{name}}", "Alice")
    print(f"{n}건 치환")
    ed.save("out.docx")

DOCX / PPTX의 텍스트 치환

from office_oxide import EditableDocument

with EditableDocument.open("slides.pptx") as ed:
    ed.replace_text("Q3", "Q4")
    ed.replace_text("2024", "2025")
    ed.save("slides_q4.pptx")

replace_text는 DOCX에서는 <w:t> 요소를, PPTX에서는 모든 슬라이드의 <a:t>를 순회하며 치환 횟수를 반환합니다.

XLSX 셀 쓰기

from office_oxide import EditableDocument

with EditableDocument.open("budget.xlsx") as ed:
    ed.set_cell(0, "A1", "Total")     # 문자열
    ed.set_cell(0, "B1", 42.5)        # 숫자 (int도 가능)
    ed.set_cell(0, "C1", True)        # 불리언
    ed.set_cell(0, "D1", None)        # 비움
    ed.save("budget.xlsx")

sheet_index는 0부터 시작; cell_ref는 표준 스프레드시트 표기법(A1, AA12)입니다.

형식 무관 IR

doc.to_ir()는 Rust의 DocumentIR을 그대로 반영하는 중첩 dict을 반환합니다 — 제목, 단락, 표, 목록, 이미지의 섹션들입니다. 파이프라인이나 LLM에 구조화된 컨텍스트를 주입할 때 유용합니다.

ir = doc.to_ir()
for section in ir["sections"]:
    print(section.get("title"))
    for el in section["elements"]:
        kind = el["kind"]   # "Heading" | "Paragraph" | "Table" | "List" | ...

바이트 기반 파이프라인

from_bytes는 서버리스/스트리밍 워크플로에서 임시 파일을 만들 필요가 없게 해줍니다:

import requests
from office_oxide import Document

data = requests.get("https://example.com/doc.docx").content
with Document.from_bytes(data, "docx") as doc:
    print(doc.to_markdown())

레거시 형식

DOC, XLS, PPT도 동일한 API로 처리합니다. 확장자에서 레거시 CFB 파서가 자동 선택되고, save_as로 모던 OOXML로 투명하게 변환할 수 있습니다:

with Document.open("legacy.doc") as doc:
    print(doc.plain_text())
    doc.save_as("legacy.docx")     # 한 줄로 DOC → DOCX

오류

파싱/IO 실패는 OfficeOxideError를 발생시킵니다. save_as의 IO 실패는 IOError로 래핑됩니다.

from office_oxide import Document, OfficeOxideError

try:
    with Document.open("weird.file") as doc:
        print(doc.plain_text())
except OfficeOxideError as e:
    print(f"office_oxide 실패: {e}")
except FileNotFoundError:
    print("파일이 없습니다")

문제 해결

증상 원인
OfficeOxideError: unsupported format: "" 경로에 확장자가 없습니다 — Document.from_bytes(data, "docx")를 사용하세요.
RuntimeError: Document is closed with 블록을 빠져나간 뒤에도 핸들을 잡고 있습니다. 새로 열어야 합니다.
ImportError: _native wheel이 플랫폼과 맞지 않습니다. pip install --force-reinstall office-oxide.
레거시 DOC가 깨져 보임 파일이 암호화되었을 수 있습니다(Word 97 RC4). office_oxide는 복호화하지 않으므로 LibreOffice로 먼저 복호화하세요.
Windows에서 Unicode 문제 바이트 경로 대신 pathlib.Path를 사용하세요. Document.open이 플랫폼 인코딩을 처리합니다.

더 보기