it-swarm.com.ru

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

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

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

27
nik

Простой пример использования 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')
52
Steven

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

(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 
5
Yang

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

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

4
lxx

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

2
Bas Bossink

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

2
James N

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

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")
1
user2921789

В качестве альтернативы функции 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
patrick

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

0
c-smile