Docx2pdf is not implemented for linux as it requires microsoft word to be installed

I am getting following error when I tried to convert docx to PDF using docx2pdf imported from docx

Google colab code:

!pip install docx2pdf
from docx2pdf import convert as doc2pdf
doc2pdf('My_document.docx')

Present output:

docx2pdf is not implemented for linux as it requires Microsoft Word to be installed

If it cannot work, can you suggest another package that I can use to convert the docx to PDF on the Google colab automatically?

asked Dec 30, 2022 at 7:25

Mainland's user avatar

Load 3 more related questions

Show fewer related questions

Я запускаю файл .gitlab.yml в Gitlab. В файле YML он запускает файлы Python, которые могут конвертировать txt> word> PDF с помощью docx2pdf. Однако он показывает, что слово Microsoft не установлено в среде gitlab linux, как я могу решить эту проблему?:

      Traceback (most recent call last):
  File "/builds/systems/ra_solutions/Python_Script/gitlab.py", line 667, in <module>
    convert(os.path.join(outDocDir,outDocName),pdfDir) # Convert to PDF
  File "/usr/local/lib/python3.10/site-packages/docx2pdf/__init__.py", line 108, in convert
    raise NotImplementedError(
NotImplementedError: docx2pdf is not implemented for linux as it requires Microsoft Word to be installed

2022-05-24 20:51

I am trying to generate a pdf report and show it in to the user in the browser. The method i used to do this was to generate the report using docx
and then use docx2pdf
in order to convert the generated report into pdf format.

My code works perfectly when i host it locally on my machine. However when i try to toast it online via heroku i get the following error:

docx2pdf is not implemented for linux as it requires Microsoft Word to be installed

The weird thing is that i am not using a linux machine. I have tried both safari and google chrome browsers and i get the same result. I find it strange because when i host the site locally, the pdf gets generated and shown in the browser exactly the way i want it. but when i upload to heroku i get the error.

The code that deals with th e conversion is:

def making_a_doc_function(request):

doc = docx.Document() 
doc.add_heading("no text")
doc.save('thisisdoc.docx')

#converting the generated docx into a pdf file
convert("thisisdoc.docx", "output.pdf")
pdf = open('output.pdf', 'rb')
response = FileResponse(pdf)
return response
import sys import json import subprocess from pathlib import Path from tqdm.auto import tqdm try: # 3.8+ from importlib.metadata import version except ImportError: from importlib_metadata import version __version__ = version(__package__) def windows(paths, keep_active): import win32com.client word = win32com.client.Dispatch(«Word.Application») wdFormatPDF = 17 if paths[«batch»]: for docx_filepath in tqdm(sorted(Path(paths[«input»]).glob(«[!~]*.doc*»))): pdf_filepath = Path(paths[«output»]) / (str(docx_filepath.stem) + «.pdf») doc = word.Documents.Open(str(docx_filepath)) doc.SaveAs(str(pdf_filepath), FileFormat=wdFormatPDF) doc.Close(0) else: pbar = tqdm(total=1) docx_filepath = Path(paths[«input»]).resolve() pdf_filepath = Path(paths[«output»]).resolve() doc = word.Documents.Open(str(docx_filepath)) doc.SaveAs(str(pdf_filepath), FileFormat=wdFormatPDF) doc.Close(0) pbar.update(1) if not keep_active: word.Quit() def macos(paths, keep_active): script = (Path(__file__).parent / «convert.jxa»).resolve() cmd = [ «/usr/bin/osascript», «-l», «JavaScript», str(script), str(paths[«input»]), str(paths[«output»]), str(keep_active).lower(), ] def run(cmd): process = subprocess.Popen(cmd, stderr=subprocess.PIPE) while True: line = process.stderr.readline().rstrip() if not line: break yield line.decode(«utf-8») total = len(list(Path(paths[«input»]).glob(«*.doc*»))) if paths[«batch»] else 1 pbar = tqdm(total=total) for line in run(cmd): try: msg = json.loads(line) except ValueError: continue if msg[«result»] == «success»: pbar.update(1) elif msg[«result»] == «error»: print(msg) sys.exit(1) def resolve_paths(input_path, output_path): input_path = Path(input_path).resolve() output_path = Path(output_path).resolve() if output_path else None output = {} if input_path.is_dir(): output[«batch»] = True output[«input»] = str(input_path) if output_path: assert output_path.is_dir() else: output_path = str(input_path) output[«output»] = output_path else: output[«batch»] = False assert str(input_path).endswith((«.docx», «.DOCX», «.doc», «.DOC»)) output[«input»] = str(input_path) if output_path and output_path.is_dir(): output_path = str(output_path / (str(input_path.stem) + «.pdf»)) elif output_path: assert str(output_path).endswith(«.pdf») else: output_path = str(input_path.parent / (str(input_path.stem) + «.pdf»)) output[«output»] = output_path return output def convert(input_path, output_path=None, keep_active=False): paths = resolve_paths(input_path, output_path) if sys.platform == «darwin»: return macos(paths, keep_active) elif sys.platform == «win32»: return windows(paths, keep_active) else: raise NotImplementedError( «docx2pdf is not implemented for linux as it requires Microsoft Word to be installed» ) def cli(): import textwrap import argparse if «—version» in sys.argv: print(__version__) sys.exit(0) description = textwrap.dedent( «»» Example Usage: Convert single docx file in-place from myfile.docx to myfile.pdf: docx2pdf myfile.docx Batch convert docx folder in-place. Output PDFs will go in the same folder: docx2pdf myfolder/ Convert single docx file with explicit output filepath: docx2pdf input.docx output.docx Convert single docx file and output to a different explicit folder: docx2pdf input.docx output_dir/ Batch convert docx folder. Output PDFs will go to a different explicit folder: docx2pdf input_dir/ output_dir/ «»» ) formatter_class = lambda prog: argparse.RawDescriptionHelpFormatter( prog, max_help_position=32 ) parser = argparse.ArgumentParser( description=description, formatter_class=formatter_class ) parser.add_argument( «input», help=«input file or folder. batch converts entire folder or convert single file», ) parser.add_argument(«output», nargs=«?», help=«output file or folder») parser.add_argument( «—keep-active», action=«store_true», default=False, help=«prevent closing word after conversion», ) parser.add_argument( «—version», action=«store_true», default=False, help=«display version and exit» ) if len(sys.argv) == 1: parser.print_help() sys.exit(0) else: args = parser.parse_args() convert(args.input, args.output, args.keep_active)

Я имею дело с проблемой, пытаясь разработать веб-приложение, часть которого преобразует загруженные файлы 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 в качестве подпроцесса. Есть ли какое-нибудь решение, кроме перехода на более сложный хостинг-сервер?

2 ответа

Лучший ответ

Справочные страницы 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 (или, по крайней мере, так оно и было для меня), но все равно работает, и сообщение об ошибке можно игнорировать.


12

jcgoble3
30 Июн 2018 в 21:11

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

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

from subprocess import  Popen
LIBRE_OFFICE = r"C:Program FilesLibreOfficeprogramsoffice.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
9 Май 2019 в 20:47

Понравилась статья? Поделить с друзьями:
  • Docx сохраненный в word 2003
  • Docx какая версия word
  • Docx для word 2013
  • Docx для word 2010
  • Docx для word 2007 скачать