アップロードされた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
がサブプロセスとして必要です。より高度なホスティングサーバーに切り替える以外に、解決策はありますか?
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
(または少なくとも私にとっては)について不平を言っているエラーメッセージを標準エラーストリームに出力しますが、それでも動作し、エラーメッセージは無視できます。
使用できるもう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)