2008-11-09 15 views
18

Pracuję nad projektem dla OSX, w którym użytkownik może wybrać kolekcję dokumentów (z dowolnej aplikacji), z których muszę wygenerować pliki PDF. W standardowym oknie dialogowym Macintosh Print znajduje się przycisk PDF z wieloma poleceniami związanymi z PDF, w tym "Zapisz jako PDF ...". Muszę jednak wygenerować plik PDF bez interakcji użytkownika. Idealnie chcę, aby to działało z dowolnym typem dokumentu.Jak programowo wygenerować plik PDF z dowolnego dokumentu na OSX?

Oto opcje mam zbadane do tej pory:

  • działania Automator. Istnieje biblioteka PDF dla Automatora, ale zapewnia ona czynności do pracy z plikami PDF, a nie generowania ich. Istnieje akcja Findera do drukowania dowolnego pliku, ale tylko do prawdziwej drukarki.
  • AppleScript. Niektóre aplikacje mają możliwość generowania plików PDF (na przykład, jeśli wyślesz "Zapisz dokument w" test.pdf "" do Pages wygeneruje PDF (ale działa to tylko dla stron - potrzebuję wsparcia dla dowolnego typu dokumentu) .
  • klienta drukarki. mógłbym stworzyć wirtualny sterownik drukarki, a następnie użyć działania Automator, ale nie podoba mi się pomysł mylące użytkownikowi dodatkową drukarkę na liście drukowania.

mam nadzieję, istnieje sposób interakcji z aktywną aplikacją, tak jakby użytkownik wykonywał następujące kroki:

  1. Do Cmd-P (otwiera okno dialogowe drukowania)
  2. Kliknij przycisk "PDF"
  3. wybierz "Zapisz jako PDF ..." (druga pozycja w menu)
  4. Type w pliku w oszczędzania dialogowym
  5. Kliknij "Save"

If to jest najlepsze podejście (prawda?), wtedy prawdziwym problemem jest: jak wysłać zdarzenia UI do zewnętrznej aplikacji (naciśnięcia klawiszy, zdarzenia myszy, wybory menu)?

Aktualizacja: Wystarczy, aby wyjaśnić jedną kwestię: dokumenty muszę konwertować do formatu PDF to dokumenty, które są tworzone przez innymi aplikacjami. Na przykład użytkownik może wybrać dokument Word lub arkusz kalkulacyjny Numbers lub rysunek OmniGraffle lub stronę internetową. Wspólnym mianownikiem jest to, że każdy z tych dokumentów ma powiązaną aplikację i ta aplikacja wie, jak ją wydrukować (a OSX wie, jak renderować wydruki do pliku PDF).

Próbki w Cocoa Dev Central nie pomagają, ponieważ generują plik PDF z mojej aplikacji.

Odpowiedz

6

Myślę, że możesz użyć applescript, aby otworzyć dokument, a następnie użyć applescript UI scripting, aby wywołać menu drukowania.

Na przykład:

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

Dzięki! To był właśnie wskaźnik, którego szukałem. –

+2

-1 Wydaje się to dobrym podejściem, jeśli otwierasz plik na safari, ale jestem pewien, że nie chcesz poprawnego kodu dla każdej możliwej aplikacji – mcgrailm

0

Wpisałem się poniższy kod z pomocą Automator (nagrywanie akcję, a następnie przeciągając konkretnych działań z „Watch Me Do” okno, w celu uzyskania jak Applescript). Jeśli chcesz wydrukować plik PDF z aplikacji innej niż Safari, konieczne może być wykonanie tego samego procesu i poprawienie tego Applescriptu wokół okna dialogowego Drukuj, ponieważ każdy program może mieć inny Print GUI.

# 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

Spójrz na program o nazwie CUPS-PDF

Jest to wirtualna drukarka dla OS X, który robi to, co robi metoda „Zapisz jako PDF” podczas drukowania za pośrednictwem zwykłej drukarce z wyjątkiem każdego zadania drukowania przeszła przez daje wynik w formacie PDF.

Po zainstalowaniu można utworzyć powłokę lub AppleScript za pomocą polecenia lp.

Na przykład po skonfigurowaniu drukarki wirtualnej można wydrukować plik test.txt i automatycznie zapisać go jako plik pdf. Aby to zrobić za pomocą AppleScript należałoby użyć następującego kodu:

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

Aplikacja CUPS-PDF zapisuje wszystkie dane wyjściowe do/Users/Shared/CUPS-PDF. Nie jestem pewien, czy możesz zmienić tę ścieżkę, ale możesz pobrać plik ze skryptu i go przenieść.

Jest jednak kilka zastrzeżeń.

Po pierwsze, polecenie lp nie może wydrukować plików .doc. Sądzę, że istnieją inne aplikacje innych firm, które pozwolą ci to zrobić.

Po drugie, aplikacja CUPS-PDF wyświetla się w panelu drukarki w Preferencjach systemowych jako posiadająca łącznik w nazwie, ale CUPS pokazuje nazwę kolejki jako znak podkreślenia. Tak więc w wierszu poleceń należy odwołać się do nazwy kolejki CUPS, która jest CUPS_PDF z podkreśleniem.

Nawet jeśli nie jest bardzo przydatne do budowania skrypt poprzez lp polecenia i nadal chcą wiązać GUI włączony następnie o wirtualną drukarkę należy zapisać pewne kroki.

1

można użyć filiżanek jak ten

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

Mam utworzonego aliasu w bash na to:

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

-bash:/System/Library/Printers/Libraries/convert: No such plik lub katalog –