Python bindings for office2pdf, a pure-Rust converter for DOCX, PPTX, and XLSX documents to PDF.
The package distribution is named office2pdf-python; the import package is office2pdf.
python -m pip install office2pdf-pythonSupported Python versions are 3.10 through 3.14. Wheels use PyO3 abi3-py310, so one wheel can support all compatible CPython versions for the same platform. CI targets Linux, macOS, and Windows.
from pathlib import Path
from office2pdf import ConvertOptions, Format, convert_bytes, convert_path
result = convert_path("report.docx")
Path("report.pdf").write_bytes(result.pdf)
options = ConvertOptions(paper_size="a4", landscape=False, include_warnings=True)
data = Path("slides.pptx").read_bytes()
result = convert_bytes(data, Format.PPTX, options)
Path("slides.pdf").write_bytes(result.pdf)The package also installs an office2pdf command:
office2pdf input.docx output.pdfThe CLI accepts DOCX, PPTX, and XLSX input paths and writes the converted PDF bytes to the output path.
Format identifies the input Office format for byte-based conversion:
Format.DOCX("docx")Format.PPTX("pptx")Format.XLSX("xlsx")
PdfStandard currently supports pdf/a-2b:
- canonical:
PdfStandard.PDF_A_2B - compatibility alias:
PdfStandard.PDF_A_2_B
PdfStandard.from_value() accepts both forms and related normalizations ("pdf/a-2b", "pdfa2b").
PaperSize.A4PaperSize.LETTERPaperSize.LEGAL
CustomPaperSize(width: float, height: float) stores explicit PDF point dimensions, matching upstream PaperSize::Custom (1 point = 1/72 inch).
All options are stored in a Python dataclass and translated to native options via to_native().
-
sheet_names: Sequence[str] | None -
sheet_filter: Sequence[str] | NoneThese are aliases for XLSX sheet selection. If both are provided, they must be equal.
-
slide_range: SlideRange | str | NoneSlideRangesupports"1-5"parsing and also accepts explicitSlideRange(1, 5). Values are normalized tostart-endstrings for native conversion. -
pdf_standard: PdfStandard | str | NoneOnly
pdf/a-2bis supported at this version. -
paper_size: PaperSize | CustomPaperSize | str | NoneString values normalize to named page sizes.
-
font_paths: Sequence[str | pathlib.Path] -
landscape: bool | None -
tagged: bool | None -
pdf_ua: bool | None -
streaming: bool -
streaming_chunk_size: int | None -
include_warnings: bool
Unsupported options are rejected to preserve API compatibility with upstream office2pdf 0.6.2:
page_range: str | Nonememory_limit_mb: int | None
pdf: byteswarnings: tuple[ConvertWarning, ...]metrics: ConvertMetrics | Nonewarning_messages: tuple[str, ...]property collecting warning messages.
Warning payloads from the native layer are mapped to typed subclasses of ConvertWarning:
UnsupportedElementWarning(format, element)PartialElementWarning(format, element, detail)FallbackUsedWarning(format, from_, to)ParseSkippedWarning(format, reason)- and a base
ConvertWarningfor legacy/unknown forms.
parse_durationcodegen_durationcompile_durationtotal_durationinput_size_bytesoutput_size_bytespage_count
Duration fields are reported in seconds.
convert_bytes(data: bytes | bytearray | memoryview, format: Format | str, options: ConvertOptions | None = None) -> ConversionResult
convert_path(path: str | pathlib.Path, options: ConvertOptions | None = None) -> ConversionResult
infer_format(path: str | pathlib.Path) -> Formatinfer_format()reads the file suffix and accepts only.docx,.pptx, or.xlsx.convert_path()validates the file extension before conversion.convert_bytes()requires an explicit inputformat.
Re-exported exception hierarchy:
Office2PdfErrorUnsupportedFormatErrorOffice2PdfIoErrorOffice2PdfParseErrorOffice2PdfRenderErrorUnsupportedEncryptionErrorUnsupportedOptionError
Version 0.3.0 exposes the upstream office2pdf 0.6.2 conversion API: file/bytes conversion, conversion options, structured warnings, metrics, and typed errors.
The upstream pdf-ops APIs (page_count, merge, split), internal IR/parser/render modules, TypeScript helpers, and WASM APIs are intentionally out of scope for this Python release.
Install Rust and Python 3.10 or newer. For local development, create and activate a virtual environment before running maturin develop:
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip maturin pytest
maturin develop --locked
python -m pytest
cargo fmt --check
cargo clippy --all-targets -- -D warningsBuild artifacts:
maturin build --locked --release --compatibility pypi
maturin sdistNo LibreOffice, Docker, Chromium, or external system service is required by this binding. Conversion behavior comes from the upstream pure-Rust crate.
The CI workflow runs tests on ubuntu-latest, macos-latest, and windows-2022 for Python 3.10, 3.11, 3.12, 3.13, and 3.14. It builds and installs the extension as an editable package, runs pytest, and performs an import smoke test.
Release-style wheel building is checked once in a dedicated wheel smoke job. Full Linux, macOS, and Windows release wheels are built by the release workflow instead of every CI matrix job. Rust fmt and clippy run in a separate Ubuntu lint job.
The release workflow runs on v* tags or manual dispatch. It builds Linux, macOS, and Windows wheels plus an sdist, then publishes with PyPI Trusted Publishing using GitHub OIDC (id-token: write). No PyPI API token is required.
Before the first publish, configure PyPI with a pending trusted publisher:
- PyPI project name:
office2pdf-python - Owner:
agentsyaml - Repository:
office2pdf-python - Workflow:
release.yml - Environment:
pypi
Create a matching GitHub environment named pypi and require manual approval for safer first releases. A pending trusted publisher can create the PyPI project on first use, but it does not reserve the project name before that first publish.
To publish a release automatically, update the version in pyproject.toml and Cargo.toml, commit the change, then push a matching tag:
git tag v0.3.0
git push origin v0.3.0The tag push starts .github/workflows/release.yml, builds artifacts, publishes to PyPI after the pypi environment approval, and creates a GitHub Release for tag-triggered runs.
This package wraps office2pdf = "0.6.2" from crates.io. The upstream project is Apache-2.0 licensed and hosted at https://github.com/developer0hye/office2pdf.