web-dev-qa-db-ja.com

pure python(Linux、libreofficeなし)でdocxをPDFに変換する

アップロードされたdocxファイルをpdfファイルに変換するWebアプリケーションを開発する際に問題を処理しています(処理後)。 python-docxおよびその他の方法では、ほとんどの処理にWordがインストールされたWindowsマシンやLinux上のlibreofficeも必要ありません(私のWebサーバーは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)

ご覧のとおり、1つのメソッドにはcomtypesが必要で、別のメソッドにはlibreofficeがサブプロセスとして必要です。より高度なホスティングサーバーに切り替える以外に、解決策はありますか?

14
Ofer Sadan

PythonAnywhereのヘルプページには、PDFファイルの操作に関する情報があります: https://help.pythonanywhere.com/pages/PDF

概要:PythonAnywhereには、PythonパッケージがPDF操作用にインストールされており、そのうちの1つが必要な処理を実行できます。ただし、abiwordへのシェルアウトは最も簡単ですシェルコマンドabiword --to=pdf filetoconvert.docxは、docxファイルをPDFに変換し、docxと同じディレクトリにfiletoconvert.pdfという名前のファイルを生成します。このコマンドに注意してください。 XDG_RUNTIME_DIR(または少なくとも私にとっては)について不平を言っているエラーメッセージを標準エラーストリームに出力しますが、それでも動作し、エラーメッセージは無視できます。

10
jcgoble3

使用できるもう1つは libreoffice です。ただし、最初のレスポンダーは、実際のcomtypesを使用した場合ほど品質が良くなることはないと述べています。

とにかく、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)
0
dfresh22