Skip to main content

doc2docx

doc2docx is a pure-Python converter from Microsoft Word 97–2003 binary .doc files to modern .docx files. The conversion engine follows the published Microsoft Office binary-format specifications and does not invoke Microsoft Word, LibreOffice, COM, Java, or another conversion executable.

The project is usable for a growing set of real documents, but it is not yet a complete implementation of every legacy Word feature. Unsupported or lossy content is reported explicitly instead of being silently presented as a fully faithful conversion.

Highlights

  • Reads CFB/OLE Word documents with deterministic, bounded parsers.
  • Opens XOR-obfuscated, classic RC4, and RC4 CryptoAPI password-protected documents when a password is supplied.
  • Preserves text, common character and paragraph formatting, fonts, styles, native numbered and bulleted lists, tables, page layout, section page and line numbering, paragraph text frames, floating table positioning, headers, and footers.
  • Converts footnotes and endnotes—including custom separators, placement, and numbering controls—plus comments, named bookmarks, safe document-local reference fields, common date/metadata/page/statistic fields, and positioned textboxes (including drawing-canvas groups flattened to a filled underlay plus independently positioned children) to native WordprocessingML structures.
  • Preserves core document metadata such as title, author, subject, keywords, revision, and creation/modification dates.
  • Restores inline and floating PNG, JPEG, BMP/DIB, TIFF, EMF, and WMF pictures in the main document and header/footer stories, including rotation, flips, tight/through wrap polygons (bounding-rectangle contour when OfficeArt omits vertices), empty PictureFrame shapes used only for wrap (no BLIP), and common floating preset shapes such as polygons, diamonds, stars (5/8/16-point), arrows (left/up/down/left-right/up-down, striped, notched, and curved right/left/up/down), smile faces, ribbons, arrow callouts, folded corners, action buttons (blank through navigation/document icons), brackets/braces, explosions/seals, no-symbol/math symbols, chevrons, bevels, waves, lightning bolts, suns, moons, cubes/cans/donuts, flowchart process/decision/data/document and extended flowchart symbols (sort, merge, delay, display, punched tape, etc.), lines, and plaques. Path-only and adjustment-formula presets (including diamonds, flowcharts, classic and modern cans, cubes, donuts, chevrons, pentagons, plaques, and cardinal/left-right arrows) are emitted as Word-style <v:shapetype> references with authoritative VML geometry (including Word SaveAs <v:handles>), and OfficeArt adjustValue/adjust2Value are passed through as VML adj (sparse/short forms are filled from the preset default on emit, e.g. ,14040 → 5400,14040, 8100 → 8100,5400) so lid depth and arrow geometry match the source.
  • Preserves confirmed embedded OLE ObjectPool storages as native DOCX embedded objects, and retains Macintosh PICT payloads for consumers that can render them.
  • Produces a structured diagnostic report for unsupported, repaired, or approximated source features.
  • Writes deterministic OPC packages using only the Python standard library at runtime.

Installation

python -m pip install msdoc2docx

Python 3.10 or newer is required.

Command line

Convert beside the input file:

doc2docx input.doc

Choose the output path and save a JSON report:

doc2docx input.doc -o output.docx --report report.json

For a password-protected document, prefer a UTF-8 password file so the secret does not appear in the process command line:

doc2docx protected.doc --password-file password.txt

Inspect a source file without converting it:

doc2docx inspect input.doc --json

Convert a directory while preserving its relative layout and write one JSON summary for successful and failed files:

doc2docx batch input-directory -o output-directory --recursive --report batch.json

Python API

from doc2docx import convert

result = convert("input.doc", "output.docx", password="secret")
print(result.report.to_dict())

The source document is opened read-only. The destination and JSON reports are written through temporary files and atomically replaced after validation or serialization; the converter will not overwrite the input file. Report paths are also checked against source and output paths, including every input and destination in batch mode.

Current limitations

Grouped/custom OfficeArt geometry and advanced drawing effects remain incomplete. Unsupported geometry with reliable OfficeArt vertices is emitted as an exact VML path in the shape's native coordinate space (including nf/ns from path NoFill/NoLine escapes); geometry with only a wrap contour is retained as an explicitly diagnosed contour approximation; geometry without such evidence is deferred. Linked or unanchored OLE storages are not activated or guessed; only confirmed embedded-object anchors are packaged. Macintosh PICT images are retained as original media, although rendering them depends on support in the DOCX consumer. The legacy macro story has no safe WordprocessingML equivalent and is deliberately omitted. Fields that can execute actions or access external content are kept as cached text. Some legacy layout behavior can only be approximated in WordprocessingML and is called out in the conversion report.

See CHANGELOG.md for milestone and release details.

doc2docx follows the same package and command conventions as xls2xlsx and ppt2pptx:

Distribution Python package / CLI Conversion
msdoc2docx doc2docx DOC to DOCX
msxls2xlsx xls2xlsx XLS to XLSX/XLSM
ppt2pptx ppt2pptx PPT to PPTX

The projects share a consistent API, CLI structure, report format, and exit status conventions. Their conversion engines remain separate because the Word, Excel, and PowerPoint binary formats use different data models.

Development

Run the standard-library test suite from a source checkout:

PYTHONPATH=src python -m unittest discover -v

Build distributable artifacts with:

python -m build

Real-document regression tests may use LibreOffice to create or render test artifacts, but LibreOffice is not used by the converter itself.

Word bilateral visual compare (Windows)

Authoritative page-image regression uses Microsoft Word COM only from scripts/ and optional tests. Install the optional visual stack into a local venv, then compare a source .doc against the converter's .docx:

python -m venv .venv
.venv\Scripts\python -m pip install -r scripts/requirements-visual.txt
$env:PYTHONPATH = (Resolve-Path .\src)
.venv\Scripts\python scripts\word_bilateral_compare.py input.doc -o evidence\case

The tool opens independent read-only temporary copies of the source DOC and output DOCX, exports both to PDF with the same Word instance, rasterizes at a fixed DPI, and writes per-page reference/actual/diff/overlay images plus a manifest.json that includes SHA-256 hashes, page metrics (MAE/RMSE/changed pixel ratio/SSIM), structure counts, and the conversion report diagnostics. LibreOffice rendering remains a development aid only and is not treated as release-level fidelity proof.

Specifications

Metadata

Release files for msdoc2docx 0.36.6

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

Source distribution (sdist)

Source distribution for msdoc2docx 0.36.6
File Size Uploaded Provenance Actions
msdoc2docx-0.36.6.tar.gz 262.5 kB Without provenance Details for msdoc2docx-0.36.6.tar.gz

Built distribution (wheel)

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

Total release size: 453.2 kB

Release files / msdoc2docx-0.36.6.tar.gz

Download URL msdoc2docx-0.36.6.tar.gz
Size 262.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a230d8cf5797b7e0a49a42385691469892d5b55524f96b3352121d440a435fca
BLAKE2b-256 checksum
How to use checksums
b9c62f081687ed308060d87a776269ad0bcc50160bd90eb53cf5be556586cea1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / msdoc2docx-0.36.6-py3-none-any.whl

Download URL msdoc2docx-0.36.6-py3-none-any.whl
Size 190.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
34a1c9303188cb2fd83c7baa25624768e908ac739c3b9a5080276d6e3d0d9d38
BLAKE2b-256 checksum
How to use checksums
875d54935db88b9db6523bcdd3652049f6a5c64251583d9460ee0a67b21f197d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for msdoc2docx 0.36.6

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