web-dev-qa-db-fra.com

Conversion de docx en pdf avec pure python (sous linux, sans libreoffice)

Je fais face à un problème en essayant de développer une application web, dont une partie convertit les fichiers docx téléchargés en fichiers pdf (après un certain traitement). Avec python-docx et d'autres méthodes, je n'ai pas besoin d'une machine Windows avec Word installé, ou même libreoffice sur linux, pour la plupart du traitement (mon serveur web est pythonanywhere - linux mais sans libreoffice et sans Sudo ou apt install autorisations). Mais la conversion au format PDF semble nécessiter l'un d'entre eux. En explorant les questions ici et ailleurs, voici ce que j'ai jusqu'à présent:

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)

Comme vous pouvez le voir, une méthode nécessite comtypes, une autre nécessite libreoffice comme sous-processus. Outre le passage à un serveur d'hébergement plus sophistiqué, existe-t-il une solution?

14
Ofer Sadan

Les pages d'aide de PythonAnywhere proposent des informations sur l'utilisation des fichiers PDF ici: https://help.pythonanywhere.com/pages/PDF

Résumé: PythonAnywhere a un certain nombre de packages Python pour la manipulation PDF installés, et l'un d'eux peut faire ce que vous voulez. Cependant, décortiquer à abiword me semble plus simple. La commande Shell abiword --to=pdf filetoconvert.docx convertira le fichier docx en PDF et produira un fichier nommé filetoconvert.pdf dans le même répertoire que le docx. Notez que cette commande affichera un message d'erreur dans le flux d'erreur standard se plaignant de XDG_RUNTIME_DIR (ou du moins il l'a fait pour moi), mais cela fonctionne toujours et le message d'erreur peut être ignoré.

10
jcgoble3

Un autre que vous pourriez utiliser est libreoffice , cependant, comme le premier répondant l'a dit, la qualité ne sera jamais aussi bonne que l'utilisation des types de comtés réels.

de toute façon, après avoir installé libreoffice, voici le code pour le faire.

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)
0
dfresh22