2008-11-09 14 views
18

Estoy trabajando en un proyecto para OSX donde el usuario puede elegir una colección de documentos (desde cualquier aplicación) de la que necesito generar PDF. El cuadro de diálogo Imprimir de Macintosh estándar tiene un botón de PDF que tiene una serie de comandos relacionados con PDF que incluyen "Guardar como PDF ...". Sin embargo, necesito generar el archivo PDF sin requerir interacciones del usuario. Lo ideal es que esto funcione con cualquier tipo de documento.¿Cómo generar programáticamente un PDF desde cualquier documento en OSX?

He aquí las opciones que he explorado hasta ahora:

  • acciones de Automator. Hay una biblioteca en PDF para Automator pero proporciona acciones para trabajar con archivos PDF, no generarlos. Hay una acción de Finder para imprimir cualquier archivo pero solo a una impresora real.
  • AppleScript. Algunas aplicaciones tienen la capacidad de generar archivos PDF (por ejemplo, si envía 'guardar documento en' test.pdf '' a Páginas, generará un PDF (pero esto solo funciona para Páginas, necesito soporte para cualquier tipo de documento) .
  • personalizados de impresora. yo podría crear un controlador de impresora virtual y luego utilizar la acción de Automator, pero no me gusta la idea de confundir al usuario con una impresora adicional en la lista de impresión.

Mi esperanza es que hay alguna forma de interactuar con la aplicación activa como si el usuario estuviera llevando a cabo los siguientes pasos:

  1. Hacer Cmd-P (abre el cuadro de diálogo de impresión)
  2. Haga clic en el botón "PDF"
  3. selecciona "Guardar como PDF ..." (segundo ítem en el menú)
  4. Tipo de nombre de archivo en cuadro de diálogo Guardar
  5. Haga clic en "Guardar"

Si ese es el mejor enfoque (¿verdad?), entonces el problema real es: ¿cómo envío eventos de IU a una aplicación externa (pulsaciones de teclas, eventos de mouse, selecciones de menú)?

Actualización: sólo para aclarar un punto: los documentos que necesito para convertir a PDF son documentos que son creados por otras aplicaciones . Por ejemplo, el usuario puede elegir un documento de Word o una hoja de cálculo de Numbers o un dibujo de OmniGraffle o una página web. El denominador común es que cada uno de estos documentos tiene una aplicación asociada y esa aplicación sabe cómo imprimirlo (y OSX sabe cómo renderizar la salida de impresión en un archivo PDF).

Por lo tanto, las muestras en Cocoa Dev Central no ayudan porque se trata de generar un PDF desde mi aplicación.

Respuesta

6

Creo que podría usar applescript para abrir un documento y luego usar applescript UI scripting para invocar el menú de impresión.

Por ejemplo:

tell application "System Events" 
     tell window of process "Safari" 
      set foremost to true 
      keystroke "p" using {command down} 
      delay 3 
      click menu button "PDF" of sheet 2 
      click menu item "Save as PDF…" of menu 1 of menu button "PDF" of sheet 2 
      keystroke "my_test.file" 
      keystroke return 
      delay 10 
     end tell 

    end tell 
+0

Gracias! Ese fue exactamente el puntero que estaba buscando. –

+2

-1 Este parece ser un buen enfoque si abres un archivo en safari pero estoy seguro de que no quieres el código correcto para cada aplicación posible – mcgrailm

0

tecleé el código de abajo con la ayuda de Automator (grabación de una acción, y luego arrastrando la acción específica de la "Míreme hacer" de la ventana con el fin de obtener la Applescript). Si desea imprimir un PDF desde una aplicación que no sea Safari, es posible que deba ejecutar el mismo proceso y modificar este Applescript en el cuadro de diálogo Imprimir, ya que cada programa puede tener una GUI de impresión diferente.

# Convert the current Safari window to a PDF 
# by Sebastain Gallese 

# props to the following for helping me get frontmost window 
# http://stackoverflow.com/questions/480866/get-the-title-of-the-current-active-window-   document-in-mac-os-x 

global window_name 

# This script works with Safari, you might have 
# to tweak it to work with other applications 
set myApplication to "Safari" 

# You can name the PDF whatever you want 
# Just make sure to delete it or move it or rename it 
# Before running the script again 
set myPDFName to "mynewpdfile" 

tell application myApplication 
    activate 
    if the (count of windows) is not 0 then 
     set window_name to name of front window 
    end if 
end tell 

set timeoutSeconds to 2.0 
set uiScript to "keystroke \"p\" using command down" 
my doWithTimeout(uiScript, timeoutSeconds) 
set uiScript to "click menu button \"PDF\" of sheet 1 of window \"" & window_name & "\" of application process \"" & myApplication & "\"" 
my doWithTimeout(uiScript, timeoutSeconds) 
set uiScript to "click menu item 2 of menu 1 of menu button \"PDF\" of sheet 1 of window \"" & window_name & "\" of application process \"" & myApplication & "\"" 
my doWithTimeout(uiScript, timeoutSeconds) 
set uiScript to "keystroke \"" & myPDFName & "\"" 
my doWithTimeout(uiScript, timeoutSeconds) 
set uiScript to "keystroke return" 
my doWithTimeout(uiScript, timeoutSeconds) 

on doWithTimeout(uiScript, timeoutSeconds) 
    set endDate to (current date) + timeoutSeconds 
    repeat 
     try 
      run script "tell application \"System Events\" 
" & uiScript & " 
end tell" 
      exit repeat 
     on error errorMessage 
      if ((current date) > endDate) then 
       error "Can not " & uiScript 
      end if 
     end try 
    end repeat 
end doWithTimeout 
2

Tome un vistazo a un programa llamado CUPS-PDF

Es una impresora virtual para OS X que hace lo mismo que el método de "Guardar como PDF", cuando de impresión en la impresora normal, excepto cada trabajo de impresión pasa a través resulta en una salida en pdf.

Una vez que lo instale, puede crear shell o AppleScripts con el comando lp.

Por ejemplo, una vez que la impresora virtual está configurada, puede imprimir test.txt y guardarla automáticamente como un pdf. Para hacer esto utilizando un AppleScript que usaría el siguiente código:

do shell script "lp -d CUPS_PDF test.txt" 

La aplicación de CUPS-PDF guarda toda la salida a/Users/Shared/CUPS-PDF. No estoy seguro si puede cambiar esa ruta, pero podría recuperar el archivo en su secuencia de comandos y moverlo.

Sin embargo, hay algunas advertencias.

En primer lugar, el comando lp no puede imprimir archivos .doc. Creo que hay algunas otras aplicaciones de terceros que te permitirán hacer esto.

En segundo lugar, la aplicación CUPS-PDF muestra en el panel Impresora de las Preferencias del Sistema el nombre del guión, pero CUPS muestra el nombre de la cola con un guión bajo. Por lo tanto, en la línea de comandos, debe consultar el nombre de la cola CUPS que es CUPS_PDF con un guión bajo.

Incluso si no lo encuentra muy útil para construir una secuencia de comandos a través de la lp comando y todavía quiere hacer participar a secuencias de comandos GUI luego tener una impresora virtual debe ahorrar algunos pasos.

1

se podía utilizar vasos como esto

on open afile 
     set filename to name of (info for afile) 
     tell application "Finder" 
      set filepath to (container of (afile as alias)) as alias 
     end tell 
     set filepath to quoted form of POSIX path of filepath 
     set tid to AppleScript's text item delimiters 
     set AppleScript's text item delimiters to "." 
     set filename to text item 1 of filename 
     set AppleScript's text item delimiters to tid 
     set afile to quoted form of POSIX path of afile 
     do shell script "cupsfilter " & afile & " > " & filepath & filename & ".pdf" 
    end open 
1

He creado un alias en bash para esto:

convert2pdf() { 
    /System/Library/Printers/Libraries/convert -f "$1" -o "$2" -j "application/pdf" 
} 
+1

-bash:/System/Library/Printers/Libraries/convert: No such archivo o directorio –

Cuestiones relacionadas