Docx в pdf с использованием openoffice без головы слишком медленно
Я использую PHPWord для генерации файлов docx. И это отлично работало. Но теперь у меня есть необходимость также предоставить доступ к некоторым из этих файлов в формате pdf.
После нескольких исследований я нашел Преобразователь PyOD, который использует OOO. Показалось довольно хорошим вариантом, так как я не хочу зависеть от сторонних веб-сервисов. Я опробовал его на своей машине, и он работает нормально, поэтому я применил его и на своем сервере. Это заняло немного больше времени, но мне удалось заставить его работать и там тоже.
Однако существует (плохая) проблема. На сервере это занимает около 21 секунды, чтобы сделать это, в то время как на моей машине это занимает не более 2.:( Это слишком много времени для моих нужд, поэтому я пытался определить, что может быть причиной этой задержки. Запуск openoffice в режиме без исцеления с созданием сокета - это нормально. Поэтому я просматривал скрипт 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()?
Любые идеи приветствуются. :)
С наилучшими пожеланиями, Беспокойный
3 answers
Мне удается устранить задержку, используя трубы вместо разъемов для подключения.
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-данные), выполняющего exec(), нет разрешения на выполнение sudo??
Возможно, распознаватель имен на сервере не знает localhost
(что было бы очень странно, но 20 секунд действительно звучит как тайм-аут DNS). Вы можете попробовать заменить его на 127.0.0.1
.
В качестве альтернативы, возможно, он выполняет поиск нормально, возвращает адреса IPv6 и IPv4 для localhost
, пытается установить соединение через IPv6 и терпит неудачу (т.Е. Компонент может не поддерживать IPv6 или не привязывается к этому интерфейсу по умолчанию) и только затем возвращается к IPv4. В этом случае средство правовой защиты было бы то же самое: заменить localhost
на 127.0.0.1
.
Жаль, что openoffice такой тяжелый. Я тоже подумывал об этом, но потом нашел более легкое решение, которое называется abiword.
Мне пришлось сгенерировать предварительные просмотры 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 и попробовать что-то вроде этого:
abiword document.docx --to=pdf