LibreOffice Integration#
Docling uses LibreOffice as an optional external tool to render two categories of content that its native parsers cannot decode:
- DrawingML elements in DOCX — charts, SmartArt, and other vector graphics that are not stored as simple embedded bitmaps
- EMF/WMF images in XLSX — legacy Windows metafile formats that openpyxl silently drops
In both cases the pipeline is: raw format → LibreOffice headless PDF → pypdfium2 render → PIL Image, after which the image is embedded into the DoclingDocument as a PictureItem like any other extracted image.
Discovery and Availability#
The shared helper get_libreoffice_cmd() locates the binary in this priority order:
shutil.which("libreoffice")(Linux/Windows PATH)shutil.which("soffice")(alternative binary name)/Applications/LibreOffice.app/Contents/MacOS/soffice(macOS default install path)
Returns None when not found. Both backends call this function and cache the result; the discovery runs at most once per document via lazy initialization flags (docx_to_pdf_converter_init in Word, xlsx_to_pdf_converter_init in Excel) .
DOCX: DrawingML Rendering#
Entry points:
get_docx_to_pdf_converter()— returns a callable(input_path, output_path)wrapping LibreOffice, orNoneget_pil_from_dml_docx()— saves a temporary DOCX containing only the target element, converts it to PDF, renders page 0 at 2× scale, then crops whitespace
In MsWordDocumentBackend, when a paragraph contains DrawingML elements (.//w:drawing) the backend calls _convert_elements_via_docx() which isolates the element into a scratch DOCX and drives get_pil_from_dml_docx. LibreOffice is also invoked as a last-resort fallback when direct PIL loading of a DrawingML picture or VML image fails .
Fallback: If LibreOffice is unavailable, get_docx_to_pdf_converter() returns None, a one-time warning is logged, and DrawingML elements are skipped entirely. Text within the same paragraph is still extracted . The warning mentions DOCLING_LIBREOFFICE_CMD but the code does not currently read that environment variable.
XLSX: EMF/WMF Image Conversion#
Entry points:
_get_libreoffice_converter()— cached factory; invokes LibreOffice with--headless --convert-to pdfand a 60-second timeout_convert_emf_to_pil()— detects WMF vs EMF by magic bytes (0xD7CDC69A), writes to a temp file, converts to PDF, renders first page at 2× scale
openpyxl raises a UserWarning for unsupported image formats (WMF/EMF) and drops them during workbook load. MsExcelDocumentBackend suppresses this warning and handles those images separately by re-reading the raw bytes directly from the XLSX zip .
Fallback: When LibreOffice is unavailable, a debug message is logged and the converter returns None. When conversion fails, a warning is logged ("Install LibreOffice for EMF/WMF support in XLSX files") and the image is skipped .
Key Source Files#
| File | Role |
|---|---|
docling/backend/docx/drawingml/utils.py | Shared LibreOffice detection, DOCX→PDF conversion helper, PIL rendering |
docling/backend/msword_backend.py | DOCX backend — DrawingML handler and fallback image conversion |
docling/backend/msexcel_backend.py | XLSX backend — EMF/WMF converter and lazy initialization |
LibreOffice is a runtime dependency only — Docling does not list it as a Python package dependency. If it is absent, affected graphics are silently skipped and all other content (text, tables, standard images) continues to convert normally.