How to convert libreoffice ODT to PDF in bash
I am using libreoffice under CentOS 6. I can convert ODT files to PDF with:
libreoffice —headless —convert-to pdf *.odt but the problem is that it only works when no document is open in libreoffice.
When I specify —env:UserInstallation=file:///path/to/some/directory as suggested in one of the comments of this question , it doesn’t help.
What am I doing wrong? It is a nuisance to close all libreoffice instances before running the before command.
3 Answers 3
That is unlikely going to work, as the suggestion in the comment is both incomplete (you cannot just specify some directory) and incorrect ( —env. should be -env. . Here is what I recommend you do:
- Stop all instances of libreoffice
Start libreoffice from the commandline without specifying —headless :
you should replace /home/username with your home directory (and adjust .config if you don’t have that on your CentOS, I did this on Ubuntu and Linux Mint). The above will create a new configuration directory for the alternate libreoffice in your .config directory, without which you would get some error about java not being found.
Now start another libreoffice from the command-line (doing so allows you to see some useful messages if things go wrong when starting the second instance), without the -env. , and while that is still running start the conversion using:
One possible approach is to install unoconv (if not already installed) and
Please see man unoconv for details
unoconv is a command line utility that can convert any file format that LibreOffice can import, to any file format that LibreOffice is capable of exporting. unoconv uses the LibreOffice’s UNO bindings for non-interactive conversion.
In some platforms it is also necessary to install libreoffice-headless \thanks
/.config/ . – Aaron D. Marasco Feb 11 ’16 at 14:32
Here is a totally different approach.
It is possible, because in recent times a series of new conversion paths were opened by Pandoc’s newly acquired capability to read ODT files.
When Pandoc reads in a file format, it converts it into an internal format, «native» (which is a form of JSON).
From its native form, it can then export the document into a whole range of other formats. Not only PDF, but also DocBook, HTML, EPUB, DOCX, ASCIIdoc, DokuWiki, MediaWiki and what-not.
Since here the wanted output format is PDF, we have another choice of different paths, provided by what Pandoc is calling a pdf-engine. Here is the list of currently available PDF engines (valid for Pandoc v2.7.2 and later — previous versions may support only a smaller list):
pdflatex: This requires LaTeX to be installed in addition to Pandoc.
xelatex: This requires XeLaTeX to be installed in addition to Pandoc (also available as an additional package to general TeX distributions).
context: This requires ConTeXt to be installed in addition to Pandoc; ConTeXt is available as an additional package to most general TeX distributions).
lualatex: This requires LuaTeX to be installed in addition to Pandoc (also available as an additional package to general TeX distributions).
pdfroff: This requires GNU Roff to be installed in addition to Pandoc.
wkhtml2pdf: This requires wkhtmltopdf to be installed in addition to Pandoc.
prince: This requires PrinceXML to be installed in addition to Pandoc.
weasyprint: This requires weasyprint to be installed in addition to Pandoc.
There are some more and newer PDF engines now integrated into Pandoc, which I have not yet used myself and which I currently cannot describe in more detail: tectonic and latexmk.
WARNING: Do not expect that the appearance of your original document will be identical in all the PDF outputs to the print preview or PDF export of the ODT! Pandoc, when converting does not preserve layouts, it preserves the contents and the structure of documents: paragraphs remain paragraphs, emphasized words remain emphasized, headings remain headings, etc. But the overall look can change considerably.
Example commands
pdflatex:
XeLaTeX:
LuaLaTeX:
ConTeXt:
GNU troff:
wkhtmltopdf:
PrinceXML:
weasyprint:
Above commands are the most basic for the conversion. Depending on the PDF engine you pick, there may be many other options possible to control the appearance of the output PDF file. For example, the following additional parameters may be added to all those paths routing through LaTeX:
which will use a custom page size (a bit larger than DIN A4) with margins of 2cm on the top edge and 1.12cm at the other three edges).
Формирование документов на основе ODT шаблонов. ODT to PDF
Здравствуйте, уважаемы хабровчане!
Не так давно мне пришлось столкнуться с типичной задачей – формировать документы с пользовательскими данными на основе шаблонов ODT средствами PHP. Звучит весьма тривиально, но намучиться пришлось сильно. Дело в том, что ни одно из доступных средств, так или иначе, не подошло. Одни библиотеки формировали документ криво, другие не поддерживали русские шрифты, третьи – двигали картинки в стиле Harlem Shake. Вот и пришлось «велосипедить».
Итак, задача вкратце:
- Обработать ODT шаблон. Заменить placeholder’ы на пользовательские значения
- Конвертировать в pdf. Показать пользователю
ЭТАП 1. Обработать ODT шаблон. Заменить placeholder’ы
Ни для кого не секрет, что ODT — это обычный архив с xml на борту. Все картинки прячутся в папке, название которой может быть любым, лишь бы на нее ссылались в файле описаний. Не будем вдаваться в подробности: достаточно лишь сказать, что за основной контент документа отвечает content.xml, за «описательную» часть – manifest.xml. Обращаю внимание, что стили текста нас не интересуют (по крайней мере, в условиях данной задачи). Копнув чуть глубже эти xml’ки выводим алгоритм:
- Распаковать архив
- Для подмены текста: парсим content.xml, заменяем placeholder’ы на нужные значения
- Для изображений: загружаем свои изображения в папку (создаем ее внутри распакованного .odt документа), парсим content.xml, заменяем placeholder’ы на frame вида
Далее, добавляем в конец manifest.xml блок вида
Алгоритм явно упрощен, зато действенен и легок. На его основе был написан класс (на коленках) odtFormat. Небольшая справка о том, как им пользоваться:
$doc_path – путь до шаблона .odt
$temp_dir – папка, в которой будут храниться временные файлы.
$name – имя placeholder’а
$value – пользовательское значение
$name – имя placeholder’a
$img_path – путь до картинки
$width – желаемая ширина изображения в документе (если не задать – ширина оригинала)
$height – желаемая длина изображения в документе (если не задать – длина оригинала)
$path_to_save – куда будем сохранять (путь+имя файла)
Остальные методы не привожу, все можно увидеть в исходнике. Тем более, что большинство вспомогательных методов взято из публичных источников. Да и сам код прост, как две копейки. Приведу лишь некоторые настройки:
Отделяет placeholder от текста слева
Отделяет placeholder от текста справа
Имя папки с пользовательскими изображениями
Ну вот, можно сказать, что файл .odt, заполненный нужными нам данными, уже сформирован. Время для второго этапа.
Внимание! Чтобы placeholder’ы заменялись корректно, при добавлении их в документ используйте «Очистить формат». Класс использовал для MS World 2013. Но что-то мне подсказывает, что содержание odt одинаково и в других версиях.
ЭТАП 2. Конвертировать в pdf. Показ пользователю
Сразу скажу, что идеального решения так и не нашел. Решений, по существу, практически нет. Перерыв «интернеты», наткнулся на горстку тяжеловесов, zend примочек и просто хлама. Так что, расскажу все, как было.
Первым делом, пытался использовать онлайн-сервисы. Сначала был Google Docs. Тут все ясно. Просто показ документа на странице через iframe, избегая самого конвертирования.
Пример:
Минусы:
- Скорость отображения
- Кривое форматирование
- При использовании сторонних библиотек для формирования odt, появлялся странный белый лист вначале документа
- Не pdf
- Онлайн
Плюсы:
- Простота
Очевидно, что данное решение долго не жило. Стоит глянуть в сторону Microsoft с их Office Apps. Интересным хинтом стало конвертирование pdf как версии для печати (встроенная функция онлайн сервиса). Таким образом, можно средствами Microsoft конвертировать файл и тут же его показать.
Пример:
Минусы
- Безумно долго
- Решение, само по себе, кривое
- Непредсказуемое поведение в разных браузерах
- Так и не удалось избавиться от окна печати
- Онлайн
Плюсы
- Качественное конвертирование
Не найдя больше достойных онлайн-вариантов, решено было использовать средства сервера. С этой задачей хорошо справляется Libreoffice. У него есть встроенный конвертер документов, работающий из командной строки. Идея заключалась в том, чтобы забрасывать сформированные odt в папку, передавать ее ключом к exec, отображать уже готовые pdf, лежащие в той же папке. Положим, что apt-get install libreoffice мы уже сделали. Осталось лишь дописать одну строку кода:
$full_path_to_file – полный путь до файлов (/var/www/*.odt)
$full_path_to_dir – полный путь до папки сохранения (/var/www/result/)
Как показать pdf в iframe, я думаю, вы и сами знаете.
Минусы
- Нужен доступ к серверу
- Тяжелый пакет libreoffice
- exec (подобные команды в коде – дело не очень-то хорошее)
Плюсы
- Заметный прирост в скорости
- Качественное форматирование
- Удобство использования готовых документов
- Абсолютно локальное решение
Заключение
При всех недостатках решения — цели выполнены. Надеюсь, что эта статья поможет избежать некоторых трудностей при выполнении подобной задачи. Всем удачного кодинга!