The LibreOffice headless cheatsheet
LibreOffice is the workhorse of self-hosted document conversion: it reads and writes the Microsoft formats, runs headless on a server, and costs nothing. It’s also documented in fragments, so everyone re-learns the same flags and the same traps from scattered forum posts.
This is the cheatsheet we wished existed. Every command was run and verified on LibreOffice 24.2 / Ubuntu 24.04 before being written down, timings and failure modes included. It’s maintained as a repo on GitHub, converterer/libreoffice-headless-cheatsheet, where corrections are welcome.
On this page: quick reference · install · filters · CSV · batching · concurrency · errors · production · references
Quick reference
| I want | Command |
|---|---|
| DOCX → PDF | soffice --headless --convert-to pdf report.docx |
| XLSX → PDF | soffice --headless --convert-to pdf data.xlsx |
| PPTX → PDF | soffice --headless --convert-to pdf deck.pptx |
| CSV → XLSX | soffice --headless --convert-to xlsx data.csv |
| DOCX → ODT | soffice --headless --convert-to odt report.docx |
| ODT → DOCX | soffice --headless --convert-to "docx:MS Word 2007 XML" report.odt |
| HTML → DOCX | soffice --headless --convert-to "docx:MS Word 2007 XML" report.html |
| DOCX → HTML | soffice --headless --convert-to "html:HTML (StarWriter)" report.docx |
| XLSX → CSV (UTF-8, comma) | soffice --headless --convert-to "csv:Text - txt - csv (StarCalc):44,34,76,1" data.xlsx |
| Semicolon CSV → XLSX | soffice --headless --infilter="CSV:59,34,76,1" --convert-to xlsx data.csv |
| PDF, first page only | soffice --headless --convert-to 'pdf:writer_pdf_Export:{"PageRange":{"type":"string","value":"1"}}' report.docx |
| Whole folder → PDF | soffice --headless --convert-to pdf *.docx --outdir out/ |
| Safe in parallel/CI | add -env:UserInstallation=file:///tmp/lo_profile_$$ |
Install and the one command
sudo apt-get install -y --no-install-recommends \
libreoffice-writer libreoffice-calc libreoffice-impress
soffice --headless --convert-to pdf report.docx
# -> report.pdf, ~2-3s on a small VPS. --outdir /path/ controls destination.
Three things that save a search later: output is named after the input (rename afterwards if you need to); existing outputs are overwritten without prompting; and Warning: failed to launch javaldx is harmless noise for conversions.
When to name the filter
Most conversions work with a bare extension. Some fail with a terse Error: no export filter, which means the import type LibreOffice chose has no default mapping to your target; HTML to DOCX is the classic case. Name the filter and it works. The strings we verified:
| Target | Filter string |
|---|---|
| PDF (Writer / Calc / Impress source) | pdf:writer_pdf_Export / pdf:calc_pdf_Export / pdf:impress_pdf_Export |
| DOCX | docx:MS Word 2007 XML |
| ODT | odt:writer8 |
| XLSX | xlsx:Calc Office Open XML |
| PPTX | pptx:Impress MS PowerPoint 2007 XML |
| HTML (from Writer) | html:HTML (StarWriter) |
| CSV | csv:Text - txt - csv (StarCalc) |
PDF export options ride after a second colon as JSON (LibreOffice 7.4+): we verified 'pdf:writer_pdf_Export:{"PageRange":{"type":"string","value":"1"}}' exports just page one. SelectPdfVersion (PDF/A) and password keys follow the same pattern; the PDF CLI parameter reference lists them all.
CSV without surprises
CSV options are a token string: ASCII code of the field delimiter, text-quote code, character set, first data row (44,34,76,1 = comma, double-quote, UTF-8, row 1). Export from a spreadsheet:
soffice --headless --convert-to "csv:Text - txt - csv (StarCalc):44,34,76,1" data.xlsx
And, the one everybody misses, importing a non-standard CSV needs --infilter, or a semicolon file lands as one column per row:
soffice --headless --infilter="CSV:59,34,76,1" --convert-to xlsx data-semicolon.csv
We verified the round-trip: semicolon in, real columns out, European decimal commas preserved. Full token meanings are in the CSV filter parameter reference.
Batch properly: startup dominates
--convert-to takes multiple files, and it matters. Same machine, same four DOCX files: 5.96s as one invocation, 13.52s as four. Globs work: soffice --headless --convert-to pdf *.docx --outdir out/.
The concurrency trap that breaks CI
Two soffice processes can’t share a user profile, and the failure is silent: the second instance exits 1 and produces no output file. No error message worth the name. If conversions “randomly go missing” in your pipeline, this is almost certainly why.
The fix is one flag, verified working with concurrent instances:
soffice --headless -env:UserInstallation=file:///tmp/lo_profile_$$ \
--convert-to pdf report.docx
In a worker pool, derive the profile path from the worker ID and reuse it (fresh profiles pay a bootstrap cost).
Errors decoded
| Symptom | Cause | Fix |
|---|---|---|
Error: no export filter | Import type can’t auto-map to the target | Name the filter explicitly (table above) |
| No output, exit 1, no error | Profile lock: another soffice on the same profile | -env:UserInstallation per instance |
Error: source file could not be loaded | Path/permission problem, or the file isn’t what its extension claims | Check readability and real format |
| One column per row after CSV import | Delimiter not declared | --infilter="CSV:59,34,76,1" |
Warning: failed to launch javaldx | Java not present | Ignore; conversions don’t need it |
| Layout/page breaks shifted | Document’s fonts missing on the server | Install the fonts at OS level |
Production notes
- Fonts: install the fonts your documents use, or layouts silently shift as substitutes kick in.
- Timeouts: wrap invocations in
timeout 120 soffice ...; corrupt inputs can hang rather than fail. - Verify output exists. Don’t trust exit codes alone; the concurrency failure above exits 1 but other silent paths exist. Check the output file is present and non-empty.
- Untrusted files: LibreOffice parses complex formats with a long CVE history. For user-uploaded documents, run it as an unprivileged user inside a container or sandbox, cap CPU/memory/runtime, and deny outbound network and filesystem access beyond the working directory.
- Parallelism means multiple instances with separate profiles, not threads; conversions are sequential within one instance.
- Fidelity: very good for typical office documents; complex Word layouts can move. Compare outputs on your real documents before committing a pipeline.
Official references
The fidelity point is the honest boundary of the tool. If you’d rather not own LibreOffice operations at all, the Converterer conversion API does DOCX, XLSX, PPTX, and 300+ other pairs as one REST call with 100 free conversions a month, and our HTML-to-PDF series applies the same hand-tested treatment to the rendering side. Either way, the cheatsheet above works entirely without us: star or correct it on GitHub.