Convert Microsoft Office documents (DOCX, XLSX, PPTX) and PDFs to Markdown
Project description
office2md
Convert Microsoft Office documents to Markdown with intelligent converter selection.
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:

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 |
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
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file office2md-0.1.3.tar.gz.
File metadata
- Download URL: office2md-0.1.3.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0611acd5af4884f1a368578bd49e8a54f2c408dc1fa84e860109eb9ccbf72d40
|
|
| MD5 |
ec71eaff48e364173a374dcd19a0e3ed
|
|
| BLAKE2b-256 |
ecf1c5954c26452243037235a17e8fcd64e903d1aecaa90d5e4bea4432f88fff
|
File details
Details for the file office2md-0.1.3-py3-none-any.whl.
File metadata
- Download URL: office2md-0.1.3-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
614ce6c0bc52830ee5f4f04f49506f685fc59f89220b7924f05dbfc0a3955c81
|
|
| MD5 |
f650a1e51a763ce8e44288a7ab1b854f
|
|
| BLAKE2b-256 |
e5d9e5e464f74f0b50f8074b888ade86cab9b5b9bb9c658b53be923071f448ca
|