Преобразование 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)