Преобразование docx в pdf с чистым python (на linux, без libreoffice)

Я имею дело с проблемой, пытающейся разработать веб-приложение, часть которого конвертирует загруженные файлы docx в pdf файлы (после некоторой обработки). При использовании python-docx и других методов для большей части обработки я не требую установки Windows с установленным словом или даже libreoffice для linux, (мой веб-сервер - это pythonanywhere - linux, но без libreoffice и без прав доступа sudo или apt install). Но преобразование в pdf, по-видимому, требует одного из них. Исследуя вопросы здесь и в других местах, это то, что у меня есть до сих пор:

import subprocess

try:
    from comtypes import client
except ImportError:
    client = None

def doc2pdf(doc):
    """
    convert a doc/docx document to pdf format
    :param doc: path to document
    """
    doc = os.path.abspath(doc) # bugfix - searching files in windows/system32
    if client is None:
        return doc2pdf_linux(doc)
    name, ext = os.path.splitext(doc)
    try:
        word = client.CreateObject('Word.Application')
        worddoc = word.Documents.Open(doc)
        worddoc.SaveAs(name + '.pdf', FileFormat=17)
    except Exception:
        raise
    finally:
        worddoc.Close()
        word.Quit()


def doc2pdf_linux(doc):
    """
    convert a doc/docx document to pdf format (linux only, requires libreoffice)
    :param doc: path to document
    """
    cmd = 'libreoffice --convert-to pdf'.split() + [doc]
    p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    p.wait(timeout=10)
    stdout, stderr = p.communicate()
    if stderr:
        raise subprocess.SubprocessError(stderr)

Как вы можете видеть, для одного метода требуются comtypes, другой требует libreoffice в качестве подпроцесса. Помимо перехода на более сложный сервер хостинга, есть ли какое-либо решение?

Ответы

Ответ 1

В справочных страницах PythonAnywhere содержится информация о работе с файлами PDF здесь: https://help.pythonanywhere.com/pages/PDF

Резюме: PythonAnywhere имеет несколько пакетов Python для обработки PDF файлов, и один из них может делать то, что вы хотите. Тем не менее, обстрел из abiword представляется мне самым легким. Команда оболочки abiword --to=pdf filetoconvert.docx преобразует файл docx в PDF и создает файл с именем filetoconvert.pdf в том же каталоге, что и docx. Обратите внимание, что эта команда выведет сообщение об ошибке в стандартный поток ошибок, XDG_RUNTIME_DIR (или, по крайней мере, это сделал для меня), но он все еще работает, и сообщение об ошибке можно игнорировать.

Ответ 2

Другой, который вы могли бы использовать, - libreoffice, однако, как сказал первый респондент, качество никогда не будет таким же хорошим, как при использовании реальных комтипов.

В любом случае, после того, как вы установили libreoffice, вот код для этого.

from subprocess import  Popen
LIBRE_OFFICE = r"C:\Program Files\LibreOffice\program\soffice.exe"

def convert_to_pdf(input_docx, out_folder):
    p = Popen([LIBRE_OFFICE, '--headless', '--convert-to', 'pdf', '--outdir',
               out_folder, input_docx])
    print([LIBRE_OFFICE, '--convert-to', 'pdf', input_docx])
    p.communicate()


sample_doc = 'file.docx'
out_folder = 'some_folder'
convert_to_pdf(sample_doc, out_folder)