Pergunta

Eu estou trabalhando em um projeto para OSX onde o usuário pode escolher uma coleção de documentos (a partir de qualquer aplicativo) que eu preciso para gerar PDF de partir. O diálogo de impressão padrão Macintosh tem um botão PDF que tem uma série de comandos relacionados a PDF incluindo "Salvar como PDF ...". No entanto, eu preciso gerar o arquivo PDF sem a necessidade de interações do usuário. I idealmente quer este trabalho com qualquer tipo de documento.

Eis as opções que eu tenho explorado até agora:

    ações
  • Automator. Há uma biblioteca PDF para Automator mas fornece ações para trabalhar com arquivos PDF, não gerando-los. Há uma ação do Finder para imprimir qualquer arquivo, mas apenas para uma impressora real.
  • AppleScript. Algumas aplicações têm a capacidade de gerar arquivos PDF (por exemplo, se você enviar 'Salvar doc em 'test.pdf'' para Pages ele irá gerar um PDF (mas isso só funciona para páginas - Preciso de suporte para qualquer tipo de documento) .
  • Printer
  • Personalizado. Eu poderia criar um driver de impressora virtual e, em seguida, usar a ação automator mas eu não gosto da idéia de confundir o usuário com uma impressora extra na lista de impressão.

A minha esperança é que há alguma maneira de interagir com o aplicativo ativo como se o usuário estava realizando os seguintes passos:

  1. Do Cmd-P (abre a janela de impressão)
  2. Clique no botão "PDF"
  3. selecione "Salvar como PDF ..." (segundo item no menu)
  4. Digite nome do arquivo no diálogo Salvar
  5. Clique em "Salvar"

Se essa é a melhor abordagem (é?), Então o verdadeiro problema é: como faço para enviar eventos de interface do usuário para um aplicativo externo (teclas, eventos de mouse, seleções de menu)

Update: Só para esclarecer um ponto: os documentos que eu preciso para converter para PDF são documentos que são criados por outras aplicações . Por exemplo, o usuário pode escolher um documento do Word ou uma planilha do Numbers ou um desenho OmniGraffle ou uma página da Web. O denominador comum é que cada um desses documentos tem uma aplicação associada e que a aplicação sabe como imprimi-lo (e OSX sabe como processar a saída de impressão para um arquivo PDF).

Assim, as amostras em Cocoa Dev Central não ajuda, porque eles são sobre a geração de um PDF a partir de minha aplicação .

Foi útil?

Solução

Eu acho que você poderia usar AppleScript para abrir um documento e, em seguida, usar applescript UI scripting para invocar menu de impressão.

Por exemplo:

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

Outras dicas

Dê uma olhada em um programa chamado CUPS-PDF

É uma impressora virtual para OS X que faz o que o método "Salvar como PDF" faz quando impressão através de sua impressora normal, exceto cada trabalho de impressão passa através dele resulta em uma saída de pdf.

Uma vez que você instalá-lo, então você pode criar shell ou AppleScripts usando o lp comando .

Por exemplo, uma vez que a impressora virtual está configurado você pode imprimir test.txt e tê-lo automaticamente salvar como pdf. Para fazer isso usando um AppleScript você usaria o seguinte código:

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

O aplicativo CUPS-PDF salva todas as saídas para / Users / Shared / CUPS-PDF. Não estou certo se você pode alterar esse caminho, mas você pode recuperar o arquivo em seu script e movê-lo.

Existem algumas ressalvas embora.

Primeiro, o lp comando não pode imprimir arquivos .doc. Eu acho que existem alguns outros aplicativos de terceiros que lhe permitirá fazer isso embora.

Em segundo lugar, os shows de aplicativos CUPS-PDF no painel da impressora das Preferências do Sistema como tendo o hífen no seu nome, mas CUPS mostra o nome da fila como tendo um sublinhado. Assim, na linha de comando que você precisa para se referir aos CUPS fila nome que está CUPS_PDF com um sublinhado.

Mesmo se você não encontrá-lo muito útil para construir um script através do lp comando e ainda querem envolver GUI scripting, em seguida, ter uma impressora virtual deve poupar alguns passos.

Você pode usar copos 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

Eu criei um alias na festa para isso:

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

Eu digitei o código abaixo com o auxílio do Automator (gravação de uma ação e, em seguida, arrastando a ação específica para fora da janela "Watch Me Do", a fim de obter o Applescript). Se você quiser imprimir um PDF a partir de um aplicativo diferente do Safari, você pode ter que passar pelo mesmo processo e ajustar isso Applescript em torno do diálogo de impressão, uma vez que cada programa pode ter uma diferente GUI Imprimir.

# 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top