.doc в pdf с использованием python
Мне поручено преобразовать тонны .doc файлов .документ pdf. И единственный способ, которым мой руководитель хочет, чтобы я это сделал, - через MSWord 2010. Я знаю, что смогу автоматизировать это с помощью Python COM automation. Только проблема в том, что я не знаю, как и с чего начать. Я попытался найти некоторые учебники, но не смог найти их (может быть, у меня есть, но я не знаю, что я ищу).
сейчас я читаю через этой. Не знаю, насколько это полезно быть.
9 ответов
простой пример использования 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')
Я работал над этой проблемой в течение половины дня, поэтому я думаю, что должен поделиться своим опытом в этом вопросе. Ответ Стивена верен, но он потерпит неудачу на моем компьютере. Есть два ключевых момента, чтобы исправить это здесь:
(1). Первый раз когда я создал слово.Объект приложения, я должен сделать его (приложение word) видимым перед открытием любых документов. (На самом деле, даже я сам не могу объяснить, почему это работает. Если я не сделаю этого на своем компьютере, программа рухнет, когда я попытаюсь откройте документ в невидимой модели, затем " Word.Объект приложения будет удален ОС. )
(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
Если вы не возражаете против использования PowerShell посмотри Эй, Сценарист! статья. Представленный код может быть принят для использования wdFormatPDF
значением перечисления WdSaveFormat
(см. здесь).
в этой статье представляет собой другую реализацию той же идеи.
стоит отметить, что ответ Стивенса работает, но убедитесь, что при использовании цикла for для экспорта нескольких файлов для размещения операторов ClientObject или Dispatch перед циклом - его нужно создать только один раз-см. мою проблему:Python win32com.клиент.Отправка цикла через документы Word и экспорт в PDF; сбой при следующем цикле
unoconv (пишется на python) и openoffice работает как безголовый демон. http://dag.wiee.rs/home-made/unoconv/
работает очень хорошо для doc, docx, ppt, pptx, xls, xlsx. Очень полезно, если вам нужно конвертировать документы или сохранять/конвертировать в определенные форматы на сервере
я попробовал принятый ответ, но не был особенно увлечен раздутым словом PDFs, которое обычно было на порядок больше, чем ожидалось. Посмотрев, как отключить диалоги при использовании виртуального PDF-принтера, я наткнулся на BULLZIP PDF Printer, и я был впечатлен его функциями. Теперь он заменил другие виртуальные принтеры, которые я использовал ранее. Вы найдете "free community edition" на их странице загрузки.
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")
вы должны начать с изучения так называемых виртуальных драйверов печати PDF. Как только вы найдете его, вы сможете написать пакетный файл, который печатает ваши файлы DOC в PDF-файлы. Вероятно, вы можете сделать это и в Python (настройка вывода драйвера принтера и выдача команды document/print в MSWord, позже можно сделать с помощью командной строки AFAIR).
в качестве альтернативы функции 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
);
полный список аргументов функции является: 'имя-файла-вывода', 'ExportFormat', 'OpenAfterExport', 'OptimizeFor', 'спектр', 'С', 'К', 'товара', 'IncludeDocProps', 'KeepIRM', 'CreateBookmarks', 'DocStructureTags', 'BitmapMissingFonts', 'UseISO19005_1','FixedFormatExtClassPtr'
Я бы предложил игнорировать вашего руководителя и использовать OpenOffice, который имеет api Python. OpenOffice встроил поддержку Python, и кто-то создал библиотеку, специфичную для этой цели (PyODConverter).
Если он не доволен результатом, скажите ему, что вам может потребоваться несколько недель, чтобы сделать это со словом.