Skip to main content

Convert Microsoft Office documents (DOCX, XLSX, PPTX) and PDFs to Markdown

Project description

office2md

Convert Microsoft Office documents to Markdown with intelligent converter selection.

Python 3.8+ License: MIT

Features

  • DOCX → Markdown with images, tables, and formatting
  • XLSX → Markdown tables (single or all sheets)
  • PPTX → Markdown with slide content and speaker notes
  • PDF → Markdown using ML-based extraction (via Docling)
  • Batch processing with recursive directory support
  • Automatic image extraction to separate folder

Installation

pip install office2md

Optional Dependencies

For best results with DOCX files, install Pandoc:

# macOS
brew install pandoc

# Ubuntu/Debian
sudo apt-get install pandoc

# Windows
choco install pandoc

For PDF support:

pip install docling

Quick Start

# Convert a single file (auto-selects best converter)
office2md document.docx

# Specify output path
office2md document.docx -o output/result.md

# Convert all files in a directory
office2md --batch ./input -o ./output

# Recursive batch processing
office2md --batch ./input -o ./output --recursive

Converter Selection

DOCX Converters (Priority Order)

Converter Quality Tables Requirements
Pandoc ⭐⭐⭐ Best ✅ Excellent External binary
Mammoth ⭐⭐ Good ⚠️ Partial Pure Python
python-docx ⭐ Basic ✅ Basic Pure Python

By default, office2md automatically selects the best available converter:

Pandoc (if installed) → Mammoth → python-docx

Force a Specific Converter

# Force Pandoc (best for complex tables)
office2md document.docx --use-pandoc

# Force Mammoth (skip Pandoc)
office2md document.docx --use-mammoth

# Force basic python-docx only
office2md document.docx --use-basic

PDF Converter

# Use Docling for PDF (ML-based, excellent for scanned docs)
office2md document.pdf --use-docling

Note: Docling is optimized for PDF files only. For DOCX, use the default converter or Pandoc.

CLI Reference

office2md [OPTIONS] INPUT

Arguments:
  INPUT                     Input file or directory (with --batch)

Options:
  -o, --output PATH         Output file or directory
  -v, --verbose             Enable verbose output

DOCX Converter Selection:
  --use-pandoc              Force Pandoc (best tables)
  --use-mammoth             Force Mammoth (good formatting)
  --use-basic               Force python-docx (fallback)
  --use-docling             Use Docling (PDF only)

Image Options:
  --skip-images             Skip image extraction
  --images-dir PATH         Custom directory for images

Batch Processing:
  --batch                   Process directory of files
  -r, --recursive           Process subdirectories

Format-Specific Options:
  --first-sheet-only        XLSX: Convert only first sheet
  --no-notes                PPTX: Skip speaker notes

Examples

Single File Conversion

# Auto-select converter
office2md report.docx

# With custom output and image directory
office2md report.docx -o docs/report.md --images-dir docs/images

# Skip images
office2md report.docx --skip-images

# Verbose output to see which converter is used
office2md report.docx -v

Batch Conversion

# Convert all supported files in directory
office2md --batch ./documents -o ./markdown

# Recursive with structure preserved
office2md --batch ./documents -o ./markdown --recursive

# Force Pandoc for all DOCX in batch
office2md --batch ./documents -o ./markdown --use-pandoc

Format-Specific

# Excel: first sheet only
office2md data.xlsx --first-sheet-only

# PowerPoint: without speaker notes
office2md presentation.pptx --no-notes

# PDF with Docling
office2md scanned-document.pdf --use-docling

Python API

from office2md import ConverterFactory

# Auto-select converter
converter = ConverterFactory.create("document.docx")
markdown = converter.convert()
converter.save(markdown)

# With options
converter = ConverterFactory.create(
    "document.docx",
    output_path="output.md",
    extract_images=True,
    images_dir="./images"
)
markdown = converter.convert()
converter.save(markdown)

Using Specific Converters

from office2md.converters import DocxConverter, PandocConverter

# DOCX with automatic fallback
converter = DocxConverter(
    "document.docx",
    use_pandoc=True  # Force Pandoc, error if unavailable
)

# Or use Pandoc directly
converter = PandocConverter("document.docx")
markdown = converter.convert()

Check Available Converters

from office2md.converters.pandoc_converter import PANDOC_AVAILABLE
from office2md.converters.mammoth_converter import MAMMOTH_AVAILABLE

print(f"Pandoc: {'✅' if PANDOC_AVAILABLE else '❌'}")
print(f"Mammoth: {'✅' if MAMMOTH_AVAILABLE else '❌'}")

Image Handling

Images are automatically extracted to a folder named {output_name}_images/:

document.docx
  ↓
document.md
document_images/
  ├── image_1.png
  ├── image_2.jpg
  └── image_3.png

Markdown references use relative paths:

![](./document_images/image_1.png)

Custom Image Directory

office2md document.docx --images-dir ./assets/images

Quality Comparison

Use the quality check script to compare converters:

python scripts/quality_check.py document.docx

Output:

============================================================
QUALITY REPORT
============================================================
Input: document.docx

====================================================================================================
Converter    Status   Time     Size       Images   Headings   Tables   Issues    
====================================================================================================
default      ✅        4.19s    24,338     30       1          0        2         
pandoc       ✅        3.25s    62,678     30       1          0        0         
====================================================================================================

🏆 BEST CONVERTER: pandoc (score: 100/100)

Supported Formats

Format Extension Converter Notes
Word .docx Pandoc/Mammoth/python-docx Auto-fallback
Excel .xlsx openpyxl All sheets or first only
PowerPoint .pptx python-pptx With/without notes
PDF .pdf Docling Requires pip install docling

Troubleshooting

"Pandoc not available"

Install Pandoc for best DOCX conversion:

# macOS
brew install pandoc

# Ubuntu
sudo apt-get install pandoc

Tables not rendering correctly

Use Pandoc for complex tables:

office2md document.docx --use-pandoc

Images have wrong paths

Ensure the images directory is created:

office2md document.docx -v  # Check verbose output for image paths

PDF conversion fails

Install Docling:

pip install docling

Development

# Clone repository
git clone https://github.com/yourusername/office2md.git
cd office2md

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=office2md

License

MIT License - see LICENSE for details.

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

office2md-0.1.2.tar.gz (25.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

office2md-0.1.2-py3-none-any.whl (28.5 kB view details)

Uploaded Python 3

File details

Details for the file office2md-0.1.2.tar.gz.

File metadata

  • Download URL: office2md-0.1.2.tar.gz
  • Upload date:
  • Size: 25.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for office2md-0.1.2.tar.gz
Algorithm Hash digest
SHA256 5fb63d38d4eb24ec2b1d3b6a6454b1daff07792ae910957bede2f65693d05ba8
MD5 ca7fc04333dfd7fd4c4bbbbee2b09138
BLAKE2b-256 57479031c32fd09b9e6c8e5a7b4539e72b60a07d6e949d61d03026cabdc3f999

See more details on using hashes here.

File details

Details for the file office2md-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: office2md-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 28.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for office2md-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 95c33c886656d91153cea49c936ad44cca9953d46a7648b2ca5900df2db8814f
MD5 35a03a6bf438a0cdd041653c6353cb8e
BLAKE2b-256 9ed9a3d6bbbbb088a7337e2ac3eb2aef33fb9d0a05c0328af44f085b430792db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page