Frequently Asked Questions¶
General Questions¶
What is JODConverter?
JODConverter (Java OpenDocument Converter) is a library that converts documents using LibreOffice or OpenOffice.
Is JODConverter free to use?
Yes. JODConverter is open-source and released under the Apache 2.0 License.
When will the next JODConverter version be released?
The project is maintained entirely on a voluntary basis in the developer's free time, so unfortunately there are no scheduled release dates.
Installation & Setup¶
Do I really need to install OpenOffice.org to use JODConverter?
Yes. In fact, JODConverter simply automates OOo operations; all actual conversions are performed by OOo. Trying to use JODConverter without OOo would be like trying to use, say, the MySQL JDBC driver without a MySQL database server. If it can't connect to a server, the driver is useless.
Do I really really need to install OpenOffice.org? There's no way to install only a few libraries/DLLs instead?
Yes you do really need a complete OOo installation. At most you can omit Base and a few optional component when installing. (Splitting OOo conversion filters into independent components is one of the goals of an OOo sub-project called ODF Toolkit, but don't hold your breath.)
How well does it convert format X to format Y?
Different people have different requirements/expectations. Why don't you just find out for yourself? Since JODConverter simply automates OOo conversions, you don't even need to install JODConverter to do some tests, you just need OOo. Manually open a document in format X with OOo, and save it as (or export it to) format Y. Voilà! No tricks, no gimmicks.
Is there an option to set X (image quality, layout mode, hidden text, etc)?
Guess what? It depends on OOo. Start up Writer, Calc, or Impress, save/export a document in the format you want to convert it to, and see which options OOo provides. Once you've found out which options you want to set you can ask on the discussion how to automate the same operation.
Is it possible to execute multiple conversions at a time?
By default, JODConverter will start a single office instance, listening for conversion request on port 2002. In order to process more than 1 conversion at the time, you must start multiple office instances.
This behavior can be achieved using the portNumbers configuration:
// This example will use 4 TCP ports, which will cause
// JODConverter to start 4 office processes when the
// OfficeManager will be started.
OfficeManager officeManager =
LocalOfficeManager
.builder()
.portNumbers(2002, 2003, 2004, 2005)
.build();
The example above shows how to start an office manager that would be able to process 4 conversions at the time. Note that the more office process you start, the more RAM will be consumed by LibreOffice or Apache OpenOffice.
How could I set password protection when converting a file to PDF?
Since JODConverter 5.0, use the PDF options:
converter
.convert(inputFile)
.to(outputFile)
.with(PdfOptions.builder().security(security -> security.openPassword("test")).build())
.execute();
With older versions, you must set 2 filter properties, EncryptFile and DocumentOpenPassword.
Here's how this could be done:
File inputFile = new File("document.doc");
File outputFile = new File("document.pdf");
Map<String, Object> filterData = new HashMap<>();
filterData.put("EncryptFile",true);
filterData.put("DocumentOpenPassword","test");
Map<String, Object> customProperties = new HashMap<>();
customProperties.put("FilterData",filterData);
LocalConverter
.builder()
.storeProperties(customProperties)
.build()
.convert(inputFile)
.to(outputFile)
.execute();
OR
Map<String, Object> filterData = new HashMap<>();
filterData.put("EncryptFile",true);
filterData.put("DocumentOpenPassword","test");
DocumentFormat format =
DocumentFormat
.builder()
.from(DefaultDocumentFormatRegistry.PDF)
.storeProperty(DocumentFamily.TEXT, "FilterData", filterData)
.build();
JodConverter
.convert(source)
.to(target)
.as(format)
.execute();
How could I specify the password of a password-protected file (input file) to convert?
Give it to the conversion:
LocalConverter.make(manager)
.convert(new File("path_to_password_protected_file"))
.to(new File("path_to_output_file"))
.password("myPassword")
.execute();
Without the password, or with a wrong one, the conversion fails with a PasswordProtectedException, whose
message says which of the two. The command line tool takes the password with --password.
When every document of a converter has the same password, the Password load property of the converter does
the same for all of them:
LocalConverter.builder()
.officeManager(manager)
.loadProperty("Password", "myPassword")
.build();
Can I merge several documents into one?
Yes, for text documents: the DocumentInserterFilter inserts another document at the end of the one being
converted. See Merging documents.
Troubleshooting¶
When converting from format X to Y, something in the output is not quite right. What happened?
As mentioned, JODConverter simply automates OOo conversions. 90% of the problems reported on the JODConverter issues page are actually OOo problems. Please try performing a manual conversion using OOo alone. If you still get the same incorrect result, then it's clearly an OOo issue. (Note that the reverse is not true. If you get different results that doesn't mean it's clearly a JODConverter issue: it may still be an OOo issue that affects only its headless mode.)
So if it is an OpenOffice.org issue and not a JODConverter one, where can I ask for more help?
The OpenOffice.org Forums is probably the best place to start. If you are sure it is a bug then you can report it as such using the OOo issue tracker.
When converting to HTML using the webapp, images are missing. Why is that?
HTML is a bit special. Converting to most other formats results in a single output file, but when converting to HTML OOo generates multiple files: one HTML file plus various image files (OOo puts them in the same directory as the HTML one). The sample webapp has no special support for HTML output (in fact its form page doesn't list HTML as an option), it just does what works for other formats i.e. returns a single file: the HTML one. Hence images are lost. The webapp does not even attempt to provide a solution for this problem, because the exact solution depends on your particular requirements. In some cases you may want to package HTML and images into a ZIP file in order to return a single file. In other cases you may want to copy HTML and images to a public path on your web server to access them directly. In all cases you should think about security implications. It's up to you.
The conversion fails with URL seems to be an unsupported one (or Could not open document). Why?
The office installation is most probably incomplete: the module that handles the document is missing (Writer for
text documents, Calc for spreadsheets, Impress for presentations). It happens with distribution packages that
install only part of the office suite, for example the Apache OpenOffice Debian packages without openoffice-calc,
openoffice-writer and their siblings. Install the missing modules; see
Running in containers.
The converted document has extra pages or a different layout. Why?
Most of the time, a font used by the document is not installed on the server, and LibreOffice replaced it with a font that has different metrics. Install the fonts the documents use, or metric-compatible ones; see Install the fonts your documents use.
Zombie processes (<defunct>) pile up in my container. Why?
The helper processes of LibreOffice are re-parented to process 1 of the container when an office process stops.
If process 1 is your Java application, nobody reaps them. Run the container with an init process (docker run --init, init: true in Docker Compose, or tini); see
Use an init process.
A conversion sometimes fails with Task did not complete within timeout. What happens?
The office process did not finish the conversion within the taskExecutionTimeout. JODConverter then kills
the process and starts a new one, so the following conversions work again. Common causes are a document that makes
LibreOffice hang, a document too big for the timeout, or an overloaded machine. Check the DEBUG logs of the
org.jodconverter logger, raise the timeout for big documents, and keep LibreOffice up to date. If a specific
document always fails, try converting it with LibreOffice alone.
The logs show Entity: line 1: parser error : Document is empty when an office process starts. Is it a problem?
No. LibreOffice writes this message on its error output at the first start of a profile, when it reads the file
where it keeps what it knows of the OpenCL devices of the machine (cache/opencl_profile.xml) before that file
exists. By default each office process starts with a new profile, so the message comes at each start.
Conversions are not affected.
JODConverter relays the output of the office process to its logs, with the
org.jodconverter.local.office.VerboseProcess logger: the standard output at the INFO level and the error
output at the WARN level (ERROR before version 5.1.1). Set that logger to ERROR or OFF to leave the output
of the office out of your logs.
Hidden sheets appear when converting a spreadsheet to PDF. How can I skip them?
Recent LibreOffice versions don't export hidden sheets. If they still appear, check the same export in LibreOffice itself: hidden rows or columns are a different setting from hidden sheets, and an old LibreOffice version may behave differently.
Known LibreOffice issues¶
These are LibreOffice behaviors that JODConverter can't change, with the workarounds known so far.
With SinglePageSheets, hyperlinks in the PDF point to local paths
When a spreadsheet is exported to PDF with the SinglePageSheets filter option, web hyperlinks may become local
file paths. See the LibreOffice discussion
and a workaround shared by a user.
With SinglePageSheets, the top rows or the first columns of an .xlsx sheet are missing
An Excel workbook remembers where each sheet was scrolled to when it was saved. When LibreOffice exports such a workbook to PDF with the SinglePageSheets filter option (spreadsheet.singlePageSheets of the PDF options), the page of a scrolled sheet starts at the saved position: the rows above it and the columns on its left are not in the PDF, while the page keeps the size of the whole sheet. A sheet saved 119 rows down loses its first 119 rows.
It happens with .xlsx files only: the same workbook stored as .xls or .ods is exported in full, and so is an .xlsx exported without SinglePageSheets. Seen with LibreOffice 25.2; the Gotenberg project met it too. A filter cannot repair it: moving the view of the loaded document back to the first cell does not change the export.
The workaround is to convert in two steps, so that the PDF is exported from a document that was not loaded from an .xlsx file:
File ods = File.createTempFile("workbook", ".ods");
converter.convert(new File("workbook.xlsx")).to(ods).execute();
converter
.convert(ods)
.to(new File("workbook.pdf"))
.with(PdfOptions.builder().spreadsheet(s -> s.singlePageSheets(true)).build())
.execute();
Converting a presentation to HTML no longer creates one image per slide
The HTML export of presentations changed in LibreOffice 24.2 and no longer produces the image-per-slide output of
earlier versions (#396). Since JODConverter 5.0,
LocalConverter.exportPages(...) exports each slide as its own image; see
Slides to Images.
On Windows, the office process crashes when a document is closed (LibreOffice 25.8.3 to 26.2)
On Windows, LibreOffice 25.8.3 to 26.2.x may crash when a document is closed through UNO, after a conversion that
was otherwise complete. The logs show Connection lost unexpectedly, sometimes a DisposedException, and the
Windows event log names soffice.bin with the exception code 0xc0000409. It does not happen at every
conversion, and it happens with text documents as well as with presentations and drawings.
This is a regression of LibreOffice, reported as tdf#172335 (also seen by the users of unoserver). It is not reproduced on Linux nor on macOS. The last version without it is 25.8.2, and it is reported fixed in 26.8.0.
JODConverter restarts the office process, so the following conversions work. Since version 5.0.1, a crash while the document is closed no longer fails the conversion, whose output is complete at that point. A crash earlier in a conversion still fails it, unless the manager has task retries (since 5.1). On Windows, prefer LibreOffice 26.8 or later, or 25.8.2 or earlier.
On macOS, every office process takes about 35 seconds to accept its first connection
When LibreOffice accepts a connection, it looks up the host name of the address 127.0.0.1. On some macOS
installations, the first such lookup of a process takes 35 seconds, and an office process is a new process each
time it starts: every start, and every restart, then waits that long before its first conversion. Nothing fails,
but a processTimeout or a taskQueueTimeout shorter than that delay can be exceeded.
We measured it on the macOS 15 and macOS 26 images of the GitHub Actions runners (Apple silicon and Intel), and not on their macOS 14 image; we do not know how common it is on other machines. To check a machine, time the lookup in a new process:
time python3 -c 'import socket; print(socket.getnameinfo(("127.0.0.1", 0), 0)[0])'
It prints localhost; on an affected machine, it takes 35 seconds to do so. The delay is in the name resolution
of macOS, before LibreOffice or JODConverter can do anything about it: the host name of the machine, the
content of /etc/hosts and the accept string of the office process make no difference. Where it happens, keep
the office processes alive (a high maxTasksPerProcess, no restart between conversions) so that the delay is
paid once.
Whenever OpenOffice.org (OOo for short) is mentioned, this can generally be interpreted to include any office suite derived from OOo such as Apache OpenOffice and LibreOffice.