.doc в pdf с использованием python
Мне поручено преобразовывать тонны файлов .doc в .pdf. И единственный способ, которым мой руководитель хочет, чтобы я сделал это, - это MSWord 2010. Я знаю, что должен автоматизировать это с помощью автоматизации Python COM. Проблема только в том, что я не знаю, как и с чего начать. Я пробовал искать некоторые уроки, но не смог найти (возможно, может быть, но я не знаю, что я ищу).
Сейчас я читаю это. Не знаю, насколько это полезно.
Ответы
Ответ 1
Простой пример с использованием 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')
Ответ 2
Я работал над этой проблемой в течение полудня, поэтому я думаю, что должен поделиться некоторыми своими впечатлениями по этому вопросу. Ответ Стивена прав, но он провалится на моем компьютере. Здесь есть два ключевых момента:
(1). В первый раз, когда я создал объект Word.Application, я должен сделать это (текстовое приложение) видимым перед открытием любых документов. (На самом деле, даже я сам не могу объяснить, почему это работает. Если я не сделаю этого на своем компьютере, программа сработает, когда я попытаюсь открыть документ в невидимой модели, тогда объект "Word.Application" будет удален OS.)
(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
Ответ 3
unoconv (writen in python) и openoffice работает как безгласный демона.
http://dag.wiee.rs/home-made/unoconv/
работает очень хорошо для doc, docx, ppt, pptx, xls, xlsx.
Очень полезно, если вам нужно конвертировать документы или сохранять/конвертировать в определенные форматы на сервере
Ответ 4
Если вы не против использования PowerShell, посмотрите Эй, сценарист! статья. Представленный код может быть принят для использования значения перечисления wdFormatPDF
WdSaveFormat
(см. здесь).
В этой статье в блоге представлена другая реализация той же идеи.
Ответ 5
Стоит отметить, что ответ Стивенса работает, но убедитесь, что при использовании цикла for для экспорта нескольких файлов для размещения операторов ClientObject или Dispatch перед циклом - его нужно только создать - см. мою проблему: Python win32com.client.Dispatch зацикливание через документы Word и экспорт в PDF; завершается сбой при следующем цикле
Ответ 6
Я попробовал принятый ответ, но не особенно интересовался раздутыми 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")
Ответ 7
Вы должны начать с изучения так называемых виртуальных драйверов печати PDF.
Как только вы его найдете, вы сможете написать пакетный файл, который печатает ваши файлы DOC в файлы PDF. Вероятно, вы тоже можете это сделать на Python (установить драйвер принтера и вывести команду document/print в MSWord, позже можно выполнить с помощью командной строки AFAIR).
Ответ 8
В качестве альтернативы функции 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'
Ответ 9
Может ли кто-нибудь помочь преобразовать поток файлов .doc в поток файлов .pdf?
Ответ 10
Я бы предложил игнорировать своего супервизора и использовать OpenOffice, у которого есть api Python. OpenOffice построил поддержку Python, и кто-то создал библиотеку, предназначенную для этой цели (PyODConverter).
Если он не доволен выходом, скажите ему, что это может занять недели, чтобы сделать это со словом.