.doc в pdf используя python - PullRequest
       74

.doc в pdf используя python

33 голосов
/ 16 мая 2011

Мне поручено конвертировать тонны файлов .doc в .pdf.И единственный способ, которым мой супервайзер хочет, чтобы я сделал это, - через MSWord 2010. Я знаю, что должен быть в состоянии автоматизировать это с помощью автоматизации Python COM.Единственная проблема в том, что я не знаю, как и с чего начать.Я пытался найти некоторые учебные пособия, но не смог их найти (может быть, у меня есть, но я не знаю, что я ищу).

Прямо сейчас я читаю это .Не знаю, насколько это будет полезно.

Ответы [ 9 ]

55 голосов
/ 16 мая 2011

Простой пример использования comtypes , преобразования одного файла, входных и выходных файлов, заданных в качестве аргументов командной строки:

import sys
import os
import comtypes.client

wdFormatPDF = 17

in_file = os.path.abspath(sys.argv[1])
out_file = os.path.abspath(sys.argv[2])

word = comtypes.client.CreateObject('Word.Application')
doc = word.Documents.Open(in_file)
doc.SaveAs(out_file, FileFormat=wdFormatPDF)
doc.Close()
word.Quit()

Вы также можете использовать pywin32 , который будет таким же, за исключением:

import win32com.client

и затем:

word = win32com.client.Dispatch('Word.Application')
7 голосов
/ 13 декабря 2016

Я работал над этой проблемой в течение полдня, поэтому я думаю, что я должен поделиться своим опытом по этому вопросу. Ответ Стивена верен, но на моем компьютере ничего не получится. Здесь есть два ключевых момента:

(1). В первый раз, когда я создал объект «Word.Application», я должен сделать его (приложение Word) видимым, прежде чем открывать какие-либо документы. (На самом деле, даже я сам не могу объяснить, почему это работает. Если я не сделаю этого на моем компьютере, программа произойдет сбой при попытке открыть документ в невидимой модели, тогда объект «Word.Application» будет удален ОС.)

(2). После выполнения (1) программа иногда будет работать хорошо, но может часто отказывать. Ошибка сбоя "COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None))" означает, что COM-сервер не сможет ответить так быстро. Поэтому я добавляю задержку, прежде чем пытаться открыть документ.

После выполнения этих двух шагов программа будет работать без сбоев. Демо-код, как показано ниже. Если вы столкнулись с такими же проблемами, попробуйте выполнить следующие два шага. Надеюсь, это поможет.

    import os
    import comtypes.client
    import time


    wdFormatPDF = 17


    # absolute path is needed
    # be careful about the slash '\', use '\\' or '/' or raw string r"..."
    in_file=r'absolute path of input docx file 1'
    out_file=r'absolute path of output pdf file 1'

    in_file2=r'absolute path of input docx file 2'
    out_file2=r'absolute path of outputpdf file 2'

    # print out filenames
    print in_file
    print out_file
    print in_file2
    print out_file2


    # create COM object
    word = comtypes.client.CreateObject('Word.Application')
    # key point 1: make word visible before open a new document
    word.Visible = True
    # key point 2: wait for the COM Server to prepare well.
    time.sleep(3)

    # convert docx file 1 to pdf file 1
    doc=word.Documents.Open(in_file) # open docx file 1
    doc.SaveAs(out_file, FileFormat=wdFormatPDF) # conversion
    doc.Close() # close docx file 1
    word.Visible = False
    # convert docx file 2 to pdf file 2
    doc = word.Documents.Open(in_file2) # open docx file 2
    doc.SaveAs(out_file2, FileFormat=wdFormatPDF) # conversion
    doc.Close() # close docx file 2   
    word.Quit() # close Word Application 
4 голосов
/ 16 октября 2014

unoconv (написанный на python) и openoffice, работающий как демон без головы. http://dag.wiee.rs/home-made/unoconv/

очень хорошо работает для doc, docx, ppt, pptx, xls, xlsx. Очень полезно, если вам нужно конвертировать документы или сохранять / конвертировать в определенные форматы на сервере

2 голосов
/ 15 мая 2013

Стоит отметить, что ответ Стивенса работает, но убедитесь, что при использовании цикла for для экспорта нескольких файлов для размещения операторов ClientObject или Dispatch перед циклом - его нужно создать только один раз - см. Мою проблему: Python win32com.client.Dispatch циклический просмотр документов Word и экспорт в PDF; не удается, когда происходит следующий цикл

2 голосов
/ 16 мая 2011

Если вы не возражаете против использования PowerShell , взгляните на этого Эй, сценарист!статья .Представленный код может быть принят для использования значения перечисления wdFormatPDF WdSaveFormat (см. здесь ). Эта статья блога представляет другую реализацию той же идеи.

1 голос
/ 01 июля 2017

Я попробовал принятый ответ, но мне не особенно понравились раздутые PDF-файлы, которые выпускал Word, которые обычно были на порядок больше, чем ожидалось.Посмотрев, как отключить диалоги при использовании виртуального PDF-принтера, я наткнулся на Bullzip PDF Printer, и я был довольно впечатлен его возможностями.Теперь он заменяет другие виртуальные принтеры, которые я использовал ранее.На их странице загрузки вы найдете «бесплатную версию сообщества».

COM API можно найти здесь , а список доступных настроек можно найти здесь .Настройки записываются в файл runonce, который используется только для одного задания на печать, а затем автоматически удаляются.При печати нескольких PDF-файлов нам необходимо убедиться, что одно задание на печать завершено, а затем запустить другое, чтобы обеспечить правильное использование настроек для каждого файла.

import os, re, time, datetime, win32com.client

def print_to_Bullzip(file):
    util = win32com.client.Dispatch("Bullzip.PDFUtil")
    settings = win32com.client.Dispatch("Bullzip.PDFSettings")
    settings.PrinterName = util.DefaultPrinterName      # make sure we're controlling the right PDF printer

    outputFile = re.sub("\.[^.]+$", ".pdf", file)
    statusFile = re.sub("\.[^.]+$", ".status", file)

    settings.SetValue("Output", outputFile)
    settings.SetValue("ConfirmOverwrite", "no")
    settings.SetValue("ShowSaveAS", "never")
    settings.SetValue("ShowSettings", "never")
    settings.SetValue("ShowPDF", "no")
    settings.SetValue("ShowProgress", "no")
    settings.SetValue("ShowProgressFinished", "no")     # disable balloon tip
    settings.SetValue("StatusFile", statusFile)         # created after print job
    settings.WriteSettings(True)                        # write settings to the runonce.ini
    util.PrintFile(file, util.DefaultPrinterName)       # send to Bullzip virtual printer

    # wait until print job completes before continuing
    # otherwise settings for the next job may not be used
    timestamp = datetime.datetime.now()
    while( (datetime.datetime.now() - timestamp).seconds < 10):
        if os.path.exists(statusFile) and os.path.isfile(statusFile):
            error = util.ReadIniString(statusFile, "Status", "Errors", '')
            if error != "0":
                raise IOError("PDF was created with errors")
            os.remove(statusFile)
            return
        time.sleep(0.1)
    raise IOError("PDF creation timed out")
0 голосов
/ 24 мая 2018

В качестве альтернативы функции SaveAs вы также можете использовать ExportAsFixedFormat, который дает вам доступ к диалоговому окну параметров PDF, который вы обычно видите в Word.При этом вы можете указать закладки и другие свойства документа.

doc.ExportAsFixedFormat(OutputFileName=pdf_file,
    ExportFormat=17, #17 = PDF output, 18=XPS output
    OpenAfterExport=False,
    OptimizeFor=0,  #0=Print (higher res), 1=Screen (lower res)
    CreateBookmarks=1, #0=No bookmarks, 1=Heading bookmarks only, 2=bookmarks match word bookmarks
    DocStructureTags=True
    );

Полный список аргументов функции: «OutputFileName», «ExportFormat», «OpenAfterExport», «OptimizeFor», «Range», «From»',' To ',' Item ',' IncludeDocProps ',' KeepIRM ',' CreateBookmarks ',' DocStructureTags ',' BitmapMissingFonts ',' UseISO19005_1 ',' FixedFormatExtClassPtr '

0 голосов
/ 16 мая 2011

Вы должны начать с исследования так называемых виртуальных драйверов печати PDF.Как только вы найдете такой файл, вы сможете написать пакетный файл, который печатает ваши DOC-файлы в PDF-файлы.Вы, вероятно, можете сделать это и в Python (настроить вывод драйвера принтера и выполнить команду document / print в MSWord, позже это можно сделать с помощью командной строки AFAIR).

0 голосов
/ 16 мая 2011

Я бы предложил игнорировать вашего супервизора и использовать OpenOffice с API-интерфейсом Python.OpenOffice имеет встроенную поддержку Python, и кто-то создал библиотеку, специально предназначенную для этой цели ( PyODConverter ).

Если он не доволен результатами, скажите ему, что это может занять несколько недель, чтобысделай это со словом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...