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()?

Любые идеи приветствуются. :)

С наилучшими пожеланиями, Беспокойный

Author: Restless, 2011-03-31

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??

 3
Author: Restless, 2011-04-05 10:39:26

Возможно, распознаватель имен на сервере не знает localhost (что было бы очень странно, но 20 секунд действительно звучит как тайм-аут DNS). Вы можете попробовать заменить его на 127.0.0.1.

В качестве альтернативы, возможно, он выполняет поиск нормально, возвращает адреса IPv6 и IPv4 для localhost, пытается установить соединение через IPv6 и терпит неудачу (т.Е. Компонент может не поддерживать IPv6 или не привязывается к этому интерфейсу по умолчанию) и только затем возвращается к IPv4. В этом случае средство правовой защиты было бы то же самое: заменить localhost на 127.0.0.1.

 2
Author: kindall, 2011-03-31 18:24:28

Жаль, что 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
 2
Author: Andrey Kuzmin, 2011-03-31 18:54:18