.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")
Si no te importa usar PowerShell eche un vistazo a este ¡Hola, tipo de scripting! artículo . El código presentado podría adoptarse para usar el valor de enumeración WdSaveFormat
de WdSaveFormat
(ver here ). Este artículo de blog presenta una implementación diferente de la misma idea.
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