Skip to main content

msdocx

Python tools for Word OOXML documents, including MS-DOCX extension namespaces (w14/w15/w16).

Overview

msdocx is a Python package for working with Word .docx files, including the published MS-DOCX specification. It supports extension namespaces that are not part of the base ISO/IEC 29500 standard.

Installation

pip install msdocx

Quick Start

from msdocx import Document
from msdocx.text_effects import TextEffect, ShadowEffect, GlowEffect

# Create a new document
doc = Document.new()

# Add content
doc.add_heading("My Document", level=1)
doc.add_paragraph("Hello, World!", bold=True, font="Calibri", size=28)

# Add a table
doc.add_table(rows=3, cols=2, width=9360)

# Add lists
doc.add_bullet_list(["Item 1", "Item 2", "Item 3"])
doc.add_numbered_list(["Step 1", "Step 2", "Step 3"])

# Save
doc.save("output.docx")

MS-DOCX Extension Features

These features are available in msdocx and cover MS-DOCX extension areas beyond the base OOXML standard:

Text Effects (w14 namespace)

from msdocx.text_effects import TextEffect, ShadowEffect, GlowEffect, ReflectionEffect, TextOutline
from msdocx.oxml.text import make_run
from msdocx.oxml.ns import qn

# Create a run with text effects
run = make_run(text="Styled Text", bold=True, size=48)
rpr = run.find(qn("w:rPr"))

effect = TextEffect(
    shadow=ShadowEffect(color="4472C4", alpha=60000),
    glow=GlowEffect(color="00FF00", radius=63500),
    reflection=ReflectionEffect(),
    ligatures="standardContextual",
    numeral_form="oldStyle",
)
effect.apply(rpr)

Content Controls with MS-DOCX Extensions

from msdocx.content_controls import ContentControl, ContentControlType

# Checkbox (w14 extension)
checkbox = ContentControl(ContentControlType.CHECKBOX)
checkbox.set_checked(True)

# Repeating section (w15 extension)
repeating = ContentControl(ContentControlType.REPEATING_SECTION)

# Entity picker (w15 extension)
picker = ContentControl(ContentControlType.ENTITY_PICKER)

# Color picker (w14 extension)
color = ContentControl(ContentControlType.COLOR)

Tracked Changes with Conflict Resolution

from msdocx.tracked_changes import TrackedChange

# Standard tracked changes
ins = TrackedChange.insert("new text", author="Alice")
del_el = TrackedChange.delete("old text", author="Bob")
del_el, ins_el = TrackedChange.replace("old", "new", author="Editor")

# MS-DOCX conflict resolution (w14 extension)
conflict_ins = TrackedChange.conflict_insert("conflict text", author="User1")
conflict_del = TrackedChange.conflict_delete("deleted in conflict", author="User2")

Collaboration Features

from msdocx.collaboration import CollaborationInfo, mark_spelling_error

# Paragraph unique IDs (w14:paraId, w14:textId) — auto-generated
info = CollaborationInfo.generate()
info.apply_to_paragraph(paragraph_element)

# Inline spelling markup
mark_spelling_error(paragraph, start_run_index=1, end_run_index=1)

Extended Compatibility Settings

from msdocx.compatibility import set_compat_mode, enable_opentype_features

# Set Word 2013+ compatibility mode
set_compat_mode(doc.settings, mode=15)

# Enable OpenType font features (MS-DOCX extension)
enable_opentype_features(doc.settings)

Accept / Reject Tracked Changes

from msdocx.tracked_changes import TrackedChange
from msdocx.oxml.ns import qn

# Accept a single insertion (keep the inserted text, remove tracking wrapper)
ins_element = body.find(f".//{qn('w:ins')}")
TrackedChange.accept_insertion(ins_element)

# Reject a single insertion (remove the inserted text entirely)
TrackedChange.reject_insertion(ins_element)

# Accept a deletion (remove the deleted text permanently)
TrackedChange.accept_deletion(del_element)

# Reject a deletion (restore the deleted text)
TrackedChange.reject_deletion(del_element)

# Accept or reject ALL changes in the document body at once
TrackedChange.accept_all(doc.body)
TrackedChange.reject_all(doc.body)

Reading Document Content

doc = Document.open("existing.docx")

# Get all text as a single string
text = doc.get_text()

# Get structured paragraph data
paragraphs = doc.get_paragraphs()
for p in paragraphs:
    print(p["text"], p["style"], p["bold"], p["italic"])

# Get tables as nested lists
tables = doc.get_tables()
for table in tables:
    for row in table:
        print(row)  # ["cell1", "cell2", ...]

# Get all comments with threading info
comments = doc.get_comments()
for c in comments:
    print(f'{c["author"]}: {c["text"]}')
    if c["parent_id"] is not None:
        print(f'  (reply to comment {c["parent_id"]})')

Comment Threading

# Create a parent comment
parent_id = doc.add_comment("Please review this section", author="Reviewer")

# Reply to the parent comment — automatically creates commentsExtended.xml
reply_id = doc.add_comment("Fixed in v2", author="Author", parent_id=parent_id)

# Read back threaded comments
comments = doc.get_comments()
# comments[1]["parent_id"] == parent_id

Specification Reference

This package implements the [MS-DOCX] specification, revision 22.1 (November 2025): https://learn.microsoft.com/en-us/openspecs/office_standards/ms-docx/b839fe1f-e1ca-4fa6-8c26-5954d0abbccd

Metadata

Release files for msdocx 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for msdocx 0.5.0
File Size Uploaded Provenance Actions
msdocx-0.5.0.tar.gz 74.3 kB Without provenance Details for msdocx-0.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for msdocx 0.5.0
File Interpreter ABI Platform Actions
msdocx-0.5.0-py3-none-any.whl Python 3 none any Details for msdocx-0.5.0-py3-none-any.whl

Total release size: 135.7 kB

Release files / msdocx-0.5.0.tar.gz

Download URL msdocx-0.5.0.tar.gz
Size 74.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6cc26f50a604763c37a51f08fdb9752f7a2e8b8003804338c4abf08c6d886b34
BLAKE2b-256 checksum
How to use checksums
a840c6c4b773c433e1b54b66c5e277517e8396ef34b78187451e35e6608088e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release files / msdocx-0.5.0-py3-none-any.whl

Download URL msdocx-0.5.0-py3-none-any.whl
Size 61.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e57a0a752dced65b0be158d903a9af21ae27b0dbef86e5d1517d988276b6a640
BLAKE2b-256 checksum
How to use checksums
1533e09b76ee3dc24dc9b6eff1a6a447bf2eb7ecb12b0be3c4d5910a135a4181
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Security for msdocx 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page