代码之家  ›  专栏  ›  技术社区  ›  Ofer Sadan

使用纯python将docx转换为pdf(在Linux上,不使用libreoffice)

  •  14
  • Ofer Sadan  · 技术社区  · 8 年前

    我在开发一个Web应用程序时遇到了一个问题,其中的一部分将上传的docx文件转换为pdf文件(经过一些处理)。与 python-docx 以及其他方法,我不需要安装了Word的Windows计算机,甚至不需要Linux上的libreoffice进行大部分处理(我的Web服务器是pythonanywhere-linux,但没有libreoffice,也没有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 回复  |  直到 7 年前
        1
  •  9
  •   jcgoble3    8 年前

    pythonanywhere帮助页面提供有关在此处使用PDF文件的信息: https://help.pythonanywhere.com/pages/PDF

    abiword abiword --to=pdf filetoconvert.docx filetoconvert.pdf XDG_RUNTIME_DIR (或者至少对我来说是这样),但它仍然有效,并且可以忽略错误消息。

        2
  •  0
  •   dfresh22    7 年前

    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)