2011-05-15 31 views
18

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)..doc a pdf usando python

Ahora estoy leyendo this. No sé lo útil que va a ser esto.

Respuesta

39

Un ejemplo sencillo usando comtypes, convertir un solo archivo, entrada y salida de los nombres de fichero dado 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 es posible usar pywin32, lo que sería igual a excepción de:

import win32com.client 

y luego:

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

Esto es exactamente lo que estaba buscando. Gracias :) – nik

+3

Para muchos archivos, considere la configuración: 'word.Visible = False' para ahorrar tiempo y el procesamiento de los archivos de palabras (la palabra MS no se mostrará de esta manera, el código se ejecutará en segundo plano) – ecoe

+0

He logrado obtener esto funciona para documentos de PowerPoint. Use 'Powerpoint.Application',' Presentations.Open' y 'FileFormat = 32'. – Snorfalorpagus

2

Si no te importa usar PowerShell echa un vistazo a este Hey, Scripting Guy! article. El código presentado podría adoptarse para usar el valor de enumeración wdFormatPDF de WdSaveFormat (ver here). This blog article presenta una implementación diferente de la misma idea.

+1

Soy un usuario de linux/Unix y más inclinado hacia python. Pero el script ps parece bastante simple y es exactamente lo que estaba buscando. Gracias :) – nik

-3

Sugeriría ignorar a su 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 no está contento con la salida, dígale que podría tomarle semanas para hacerlo con la palabra.

0

Debe comenzar investigando los llamados controladores de impresión virtual 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).

2

unoconv (escrito en python) y OpenOffice ejecutándose 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

2

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á borrado por SO.)

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

Probé la respuesta aceptada, pero no tenía un interés particular en los archivos PDF hinchados Palabra estaba produciendo, que era por lo general 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") 
Cuestiones relacionadas