Я использую PHPWord для генерации файлов docx. И он отлично работает. Но теперь мне нужно также предоставить некоторые из этих файлов в pdf-версии.
После нескольких исследований я нашел PyODConverter, который использует OOo. Это был неплохой вариант, поскольку я не хочу зависеть от сторонних веб-сервисов. Я попробовал его на своей машине, и он работает оштрафован, поэтому я применил его и на моем сервере. Это заняло немного больше времени, но мне удалось заставить его работать там.
Однако есть (плохая) проблема. На сервере это занимает около 21 секунды, чтобы сделать это, в то время как на моей машине это не занимает больше времени 2. 🙁 Это слишком много времени для моих нужд, поэтому я пытался определить, что может вызвать это Запуск openoffice в режиме healess с созданием сокета в порядке. Поэтому я смотрел скрипт python, пытаясь выяснить, какая инструкция может замедлить работу. Я сузил ее до этой строки:
context = resolver.resolve("uno:socket,host=127.0.0.1,port=8100;urp;StarOffice.ComponentContext")
Это действие, которое занимает около 20 секунд для выполнения. Код, в который он вставлен:
localContext = uno.getComponentContext() resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) try: context = resolver.resolve("uno:socket,host=127.0.0.1,port=8100;urp;StarOffice.ComponentContext") except NoConnectException: raise DocumentConversionException, "failed to connect to OpenOffice.org on port %s" % port self.desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
Какие-нибудь подсказки о том, что может вызвать эту задержку? Я исключил документ, который я пытаюсь преобразовать, поскольку эти операции происходят до этого. Это может быть проблема с «uno»? Или, возможно, еще одна недостающая библиотека, которая может вызвать бесполезное тестирование во время операции resolve ()?
Любые идеи приветствуются. 🙂
С наилучшими пожеланиями, Беспокойный
Мне удается устранить задержку, используя для соединения соединения вместо сокетов.
context = resolver.resolve("uno:pipe,name=myuser_OOffice;urp;StarOffice.ComponentContext")
У меня все еще есть одна проблема, хотя … пользователь, выполняющий скрипт python, должен быть тем же самым, что начинает OOo, потому что все работает нормально. Обычно это не было большой проблемой, но я пытаюсь выполнить python из своего веб-приложения, и мне все еще не удалось заставить его работать. Я пытаюсь что-то вроде этого:
exec('sudo -u#1000 -s python path/to/DocumentConverter.py filename.docx filename.pdf');
Я ничего не получаю от этого .. и я не понимаю почему. Может быть, пользователь (www-data) работает exec () не имеет разрешения на выполнение sudo ??
Возможно, имя resolver на сервере не знает localhost
(что было бы очень странно, но 20 секунд звучит как тайм-аут DNS). Вы можете попробовать заменить его на 127.0.0.1
.
В качестве альтернативы, возможно, он отлично справляется с поиском, возвращая оба адреса IPv6 и IPv4 для localhost
, пытаясь установить соединение через IPv6 и сбой (т. Е. Компонент может не поддерживать IPv6 или не привязываться к этому интерфейсу по умолчанию) и только затем возвращается к IPv4. В этом случае средство будет одинаковым: замените localhost
на 127.0.0.1
.
Жаль, что openoffice настолько тяжела. Я тоже это рассматривал, но тогда я нашел более легкое решение, которое было бы словом.
Мне пришлось создать предварительный просмотр 4 первых страниц из загруженного документа. Это то, что я сделал:
abiword document.doc --to=ps --exp-props="pages:1-4" gs -q -dNOPAUSE -dBATCH -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r72 -sDEVICE=pnggray -sOutputFile=preview%d.png document.ps
Таким образом, вы можете получить последнее абижнее и попробовать что-то вроде этого:
abiword document.docx --to=pdf