Log In Sign Up

Blog

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 wantCommand
DOCX → PDFsoffice --headless --convert-to pdf report.docx
XLSX → PDFsoffice --headless --convert-to pdf data.xlsx
PPTX → PDFsoffice --headless --convert-to pdf deck.pptx
CSV → XLSXsoffice --headless --convert-to xlsx data.csv
DOCX → ODTsoffice --headless --convert-to odt report.docx
ODT → DOCXsoffice --headless --convert-to "docx:MS Word 2007 XML" report.odt
HTML → DOCXsoffice --headless --convert-to "docx:MS Word 2007 XML" report.html
DOCX → HTMLsoffice --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 → XLSXsoffice --headless --infilter="CSV:59,34,76,1" --convert-to xlsx data.csv
PDF, first page onlysoffice --headless --convert-to 'pdf:writer_pdf_Export:{"PageRange":{"type":"string","value":"1"}}' report.docx
Whole folder → PDFsoffice --headless --convert-to pdf *.docx --outdir out/
Safe in parallel/CIadd -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:

TargetFilter string
PDF (Writer / Calc / Impress source)pdf:writer_pdf_Export / pdf:calc_pdf_Export / pdf:impress_pdf_Export
DOCXdocx:MS Word 2007 XML
ODTodt:writer8
XLSXxlsx:Calc Office Open XML
PPTXpptx:Impress MS PowerPoint 2007 XML
HTML (from Writer)html:HTML (StarWriter)
CSVcsv: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

SymptomCauseFix
Error: no export filterImport type can’t auto-map to the targetName the filter explicitly (table above)
No output, exit 1, no errorProfile lock: another soffice on the same profile-env:UserInstallation per instance
Error: source file could not be loadedPath/permission problem, or the file isn’t what its extension claimsCheck readability and real format
One column per row after CSV importDelimiter not declared--infilter="CSV:59,34,76,1"
Warning: failed to launch javaldxJava not presentIgnore; conversions don’t need it
Layout/page breaks shiftedDocument’s fonts missing on the serverInstall 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.