Pregunta

Estoy trabajando en un proyecto para OSX donde el usuario puede elegir una colección de documentos (desde cualquier aplicación) desde la que necesito generar archivos PDF. El cuadro de diálogo estándar Imprimir de Macintosh tiene un botón 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. Idealmente quiero que esto funcione con cualquier tipo de documento.

Estas son las opciones que he explorado hasta ahora:

  • Acciones del automatizador. Hay una biblioteca de PDF para Automator, pero proporciona acciones para trabajar con archivos PDF, no para generarlos. Hay una acción Finder para imprimir cualquier archivo pero solo en 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) ).
  • Impresora personalizada. Podría crear un controlador de impresora virtual y luego usar la acción del automatizador, pero no me gusta la idea de confundir al usuario con una impresora adicional en la lista de impresión.

Espero que haya alguna forma de interactuar con la aplicación activa como si el usuario estuviera realizando los siguientes pasos:

  1. Do Cmd-P (abre el diálogo de impresión)
  2. Haga clic en el " PDF " botón
  3. Seleccione " Guardar como PDF ... " (segundo elemento del menú)
  4. Escriba el nombre del archivo en el cuadro de diálogo Guardar
  5. Haga clic en "Guardar"

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

Actualización: Solo para aclarar un punto: los documentos que necesito convertir a PDF son documentos 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 representar la salida de impresión en un archivo PDF).

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

¿Fue útil?

Solución

Creo que podría usar AppleScript para abrir un documento y luego usar scripts de UI de AppleScript 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

Otros consejos

Eche un vistazo a un programa llamado CUPS-PDF

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

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

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

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

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

Sin embargo, hay algunas advertencias.

Primero, el comando lp no puede imprimir archivos .doc. Sin embargo, creo que hay otras aplicaciones de terceros que te permitirán hacer esto.

Segundo, la aplicación CUPS-PDF muestra en el panel Impresora de Preferencias del Sistema que tiene el guión en su nombre, pero CUPS muestra el nombre de la cola con un guión bajo. Por lo tanto, en la línea de comando debe hacer referencia al nombre de la cola CUPS que es CUPS_PDF con un guión bajo.

Incluso si no le resulta muy útil crear un script a través del comando lp y todavía desea involucrar las secuencias de comandos de la GUI, tener una impresora virtual debería ahorrarle algunos pasos.

podrías usar tazas como esta

    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

He creado un alias en bash para esto:

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

Escribí el código a continuación con la ayuda de Automator (grabando una acción y luego arrastrando la acción específica fuera de la ventana '' Watch Me Do '' para obtener el 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 alrededor del 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top