Как стать автором
Обновить

Комментарии 20

Тоже недавно писал конвертацию DOCX в PDF, ни один вариант с использованием PHPOffice и PHP-конвертеров не дал приемлемого результата, кроме Libre Office. Причём я сначала хотел использовать unoconv, но он уверенно конвертировал файлы только из консоли (и у него под капотом тоже libreoffice), а из кода ни в какую.

Да, unoconv по сути аналогичная обертка, но на питоне. Я сперва начал использовать ее, даже написал модуль на php под нее, не найдя подходящего. И для laravel в том числе. Но потом понял, что в unoconv есть свои проблемы и автор его не очень активно поддерживает. Поэтому решил, что лучше сделать обертку поверх libreofffice. Если будут возникать какие-то трудности, то мне их легче будет быстренько пофиксить.

Unoconv — это небольшая python обертка над unoAPI LibreOffice(OpenOffice). По сути один файл, который можно расковырять и привести к приемлемому функционалу, заменив прием аргументов из нужного источника.
Так же писал подобный микросервис для себя (из unoconv) и с лета собираюсь написать об этом :)
что касается doc И excel — майкрософтовский офис сам их конвертит — достаточно сохранить HTML файлы с расширением docx или, соответственно, xslx

Что касается граблей — нужно делать inline стили и верстать HTML одной таблицей иначе части документа формируются отдельно и расползаются

Раньше тоже так делал. Но при редактировании и последующем сохранении такого документа возникало сообщение, мол, переконвертировать ли документ в формат ворда (не помню точно формулировку). Свежий LibreOffice тоже спрашивает. А вот офис от Microsoft давно не использовал. Новые версии MS Office задают такой вопрос?

последние не пробовал думаю да — обычный вопрос любой проги если она собирается пересохранить файл с другой структурой
А вот либреофис как то некоректно открывал
Точнее майкрософт сразу конвертил и открывал уже как родной а либре по моему открывал как HTML
но в целом проблем не было даже с бухгалтерсикими отчетомаи типа главной книги и налоговыми накладными
главное верстать внутри одного table
Внедряли на проекте конвертертацию на основе LibreOffice. Нужно было сконвертить около 200000 doc-файлов в html. Процесс периодически зависал, приходилось ручками конвертор перезапускать.

На такой случай в обертке можно задать таймаут. По умолчанию конвертеру дается 60 секунд, после чего будет выброшено исключение.

Как на счет формирования документов в формате openoffice(odt, ods). Сами эти файлы представляют zip архив, в котором находятся xml файлы. Правите content.xml, запаковываете обратно в zip, переименовывываете архив обратно в odt или ods. После этого можно конвертировать в любой формат. Это сложнее, т.к. надо разбираться с xml. Зато все возможности, которых нет в html. А разметка в xml очень похожа на html

У меня была задача конвертировать html в PDF. К сожалению, так и не смог найти подходящий инструмент. Пытался использовать DomPDF, HTML2PDF. У них у всех одна болезнь не понимают даже среднюю верстку. А документ был как раз счет фактурой со сложными таблицами. Пришлось верстать с нуля с помощью fPDF(tPDF).
Libre office не использовал.

Вот вопрос. Как хром быстро конвертирует в PDF при печати? Нужно всего лишь выбрать PDF принтер и все, PDF готов, каким бы сложным не был документ.

По моей практике наиболее быстрым и при этом наиболее качественным оказался конвертер wkhtmltopdf. Я работал с ним через https://github.com/barryvdh/laravel-snappy

Посмотрите wkhtmltopdf — использует webkit для конвертирования html в PDF
Забыли добавить, что libreoffice для запуска требует установленного JRE
В плане конвертации из Word/Exel есть еще docx4j. Заявляют, что умеют читать те же docx не хуже ворда, ну и конвертировать куда надо. Никто не пробовал? Если конвертирует не плохо, то можно и оболочки написать. LibreOffice вот не всегда понимает, например, математические формулы.

Спасибо, попробую как будет возможность. Обертка для PHP не помешает.

Провозился со всеми конвертерами, которые в связке с PHPWord шли — mpdf, dompdf, tcpdf и ни один не смог даже самую простую таблицу отпечатать с отсутствующим border (opacity 0). С кирилицей у 2 из 3 конверторов жестокие проблемы — dompdf, tcpdf и чтобы всё взлетело надо доставлять шрифты, конфигурировать и то не факт, что всё взлетит. Из коробки кирилицу только mpdf подцепил и всё распечатал без ???
С изображениями тоже беда — достаточно в редакторе добавить свойство «Under text» изображению и ни один конвертер не отпечатает изображение, от слова совсем. При попытке позиционирования изображения в режиме absolute — +-1 пиксель куда-то не туда и всё, в генерируемом pdf нет изображения.

В итоге плюнул я на эту возню и решил, что лучше использовать libreoffice с его конвертером. Правда здесь у меня тоже юмор — рабочая машина mac, сервер — centos… надеюсь, что тестировать это будет не так тяжко, как возиться с кучей полурабочих библиотек.

За статью благодарность! За конвертер — отдельно. Хоть велосипеды писать не надо.
Дополню свой же комментарий, потому что пришлось понаступать на грабли. Конвертил я docx в pdf и при запуске из консоли была ошибка LibreOffice с кодом 77. Пофиксил её вот так:

$converter = new Converter('soffice');
$params = (new LowrapperParameters())
            ->setInputFile($docxInvoice)
            ->setOutputFile($pdfInvoice)
            ->setOutputFormat(Format::TEXT_PDF);
$converter->addOption('-env:UserInstallation=file://'. sys_get_temp_dir(), 'libreoffice');
$converter->convert($params);


На что обратить внимание:
$converter->addOption('-env:UserInstallation=file://'. sys_get_temp_dir(), 'libreoffice');


Несмотря на --headless параметр запуска LibreOffice пользовательская конфигурация сохраняется LibreOffice в домашней директории. На сервере (да и у меня локально) пользователь, запускающий процесс LibreOffice не имет доступа к write домашней директории, поэтому, чтобы не давать лишних прав — указываем другое место сохранения настроек. После этого всё заработало как по маслу.
Дополню свой комментарий, потому что я себе весь мозг вынес этим — проблема в том, что текущая реализация библиотеки (от автора поста, да и в целом имеющихся решений) не позволяет работать с несколькими параллельными (для поисковиков: multiple instances in command line libreoffice) инстансами soffice / libreoffice и, как в моём случае, одновременный запуск генерации двух счетов приводит к выбрасыванию исключения.

Как исправить?
Где я нашел решение: document-foundation-mail-archive.969070.n3.nabble.com/How-to-run-multiple-instances-of-Writer-simultaneously-tp4225101p4225390.html

Цитирую, чтобы текст никуда не исчез:

Just wanted to follow up on this thread. Running multiple Writers in the same (single) soffice.bin process seems to incur noticeable performance penalties. Therefore, in order to run several soffice.bin processes:

— Get a uuid string.
— Create random folder in /tmp/soffice-dir-uuid for the soffice.bin process.
— Optional as Matthew Francis suggested: copy a cached soffice folder into /tmp/soffice-dir-uuid (to improve startup performance).
— Run soffice --headless --accept=«pipe,name=soffice-pipe-uuid;urp;StarOffice.ServiceManager» -env:UserInstallation=file:///tmp/soffice-dir-uuid (Or call /path/to/soffice.bin directly.)


Пилим под себя и получаем вот такой итог (с использованием библиотеки от автора поста):

$converter->addOption('--nolockcheck');
$converter->addOption('--accept="pipe,name='. uniqid('libreoffice') .';urp;StarOffice.ServiceManager"');
$converter->addOption('-env:UserInstallation=file://'. sys_get_temp_dir() . uniqid('libreoffice'));


Как предлагали на форуме (возможно в том же треде) — один из вариантов ускорения запуска libreoffice в --headless режиме, так это не создавать каждый раз новую структуру директории для флага UserInstallation, а создать один раз дефолтную и потом её только копировать во временную зону.

Хух. Надеюсь это реально кому-то поможет!
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.