python pdf automation ms-word win32com

.doc a pdf usando python



automation ms-word (9)

Tengo la tarea de convertir toneladas de archivos .doc a .pdf. Y la única forma en que mi supervisor quiere que haga esto es a través de MSWord 2010. Sé que debería ser capaz de automatizar esto con la automatización COM de python. El único problema es que no sé cómo ni por dónde empezar. Traté de buscar algunos tutoriales pero no pude encontrar ninguno (puede ser que lo haya hecho, pero no sé lo que estoy buscando).

En este momento estoy leyendo this . No sé lo útil que va a ser esto.


Como alternativa a la función SaveAs, también puede usar ExportAsFixedFormat, que le da acceso al cuadro de diálogo de opciones de PDF que normalmente vería en Word. Con esto puede especificar marcadores y otras propiedades del documento.

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 );

La lista completa de los argumentos de función es: ''OutputFileName'', ''ExportFormat'', ''OpenAfterExport'', ''OptimizeFor'', ''Range'', ''From'', ''To'', ''Item'', ''IncludeDocProps'', ''KeepIRM'', ''CreateBookmarks '','' DocStructureTags '','' BitmapMissingFonts '','' UseISO19005_1 '','' FixedFormatExtClassPtr ''


Deberías comenzar investigando los llamados controladores virtuales de impresión PDF. Tan pronto como encuentre uno, podrá escribir un archivo por lotes que imprima sus archivos DOC en archivos PDF. Probablemente también pueda hacerlo en Python (configure la salida del controlador de la impresora y emita el comando de documento / impresión en MSWord, luego puede hacerlo utilizando la línea de comando AFAIR).


He trabajado en este problema durante medio día, así que creo que debería compartir algo de mi experiencia en este asunto. La respuesta de Steven es correcta, pero fallará en mi computadora. Hay dos puntos clave para solucionarlo aquí:

(1) La primera vez que creé el objeto ''Word.Application'', debería hacerlo visible (la aplicación de la palabra) antes de abrir cualquier documento. (En realidad, ni siquiera yo mismo puedo explicar por qué funciona esto. Si no hago esto en mi computadora, el programa se bloqueará cuando intente abrir un documento en el modelo invisible, luego el objeto ''Word.Application'' será eliminado por OS.)

(2) Después de hacer (1), el programa funcionará bien a veces pero puede fallar a menudo. El error de bloqueo "COMError: (-2147418111, ''Call was rejected by callee.'', (None, None, None, 0, None))" significa que el Servidor COM puede no ser capaz de responder tan rápidamente. Así que agrego un retraso antes de intentar abrir un documento.

Después de hacer estos dos pasos, el programa funcionará perfectamente sin fallas. El código de demostración es el siguiente. Si ha encontrado los mismos problemas, intente seguir estos dos pasos. Espero eso ayude.

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


Probé la respuesta aceptada, pero no estaba particularmente interesado en los archivos PDF inflados que Word estaba produciendo, que generalmente era un orden de magnitud mayor de lo esperado. Después de ver cómo desactivar los diálogos al usar una impresora virtual PDF, me encontré con la impresora Bullzip PDF y me han impresionado bastante sus características. Ahora reemplazó las otras impresoras virtuales que utilicé anteriormente. Encontrará una "edición de comunidad gratuita" en su página de descarga.

La API COM se puede encontrar here y se puede encontrar una lista de las configuraciones utilizables here . Los ajustes se escriben en un archivo "runonce" que se usa solo para un trabajo de impresión y luego se elimina automáticamente. Al imprimir varios PDF, debemos asegurarnos de que un trabajo de impresión finalice antes de comenzar otro para asegurarnos de que la configuración se use correctamente para cada archivo.

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



Sugiero ignorar a tu supervisor y usar OpenOffice que tiene una API de Python. OpenOffice ha incorporado soporte para Python y alguien creó una biblioteca específica para este propósito ( PyODConverter ).

Si él no está contento con la salida, dígale que le puede tomar semanas hacerlo con la palabra.


Un ejemplo simple usando comtypes , convirtiendo un solo archivo, entrada y salida de nombres de archivos dados como argumentos de línea de comandos:

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()

También podría usar pywin32 , que sería lo mismo excepto para:

import win32com.client

y entonces:

word = win32com.client.Dispatch(''Word.Application'')


Vale la pena señalar que la respuesta de Stevens funciona, pero asegúrese de que si utiliza un bucle for para exportar varios archivos para colocar las instrucciones ClientObject o Dispatch antes del bucle, solo necesita crearse una vez, vea mi problema: Python win32com.client.Dispatch looping a través de documentos Word y exportar a PDF; falla cuando ocurre el siguiente ciclo


unoconv (escrito en python) y openoffice funcionando como un daemon sin cabeza. http://dag.wiee.rs/home-made/unoconv/

funciona muy bien para doc, docx, ppt, pptx, xls, xlsx. Muy útil si necesita convertir documentos o guardar / convertir a ciertos formatos en un servidor