Подтвердить что ты не робот

Как программно генерировать PDF из любого документа в OSX?

Я работаю над проектом для OSX, где пользователь может выбрать коллекцию документов (из любого приложения), которые мне нужны для создания PDF. В стандартном диалоговом окне "Печать Macintosh" есть кнопка PDF, в которой есть несколько команд, связанных с PDF, включая "Сохранить как PDF...". Однако мне нужно создать PDF файл, не требуя взаимодействия с пользователем. Я в идеале хочу, чтобы это работало с любым типом документа.

Здесь варианты, которые я изучил до сих пор:

  • Действия автомата. Там есть библиотека PDF для Automator, но она обеспечивает действия для работы с файлами PDF, а не для их создания. Существует действие Finder для печати любого файла, но только для реального принтера.
  • AppleScript. Некоторые приложения имеют возможность генерировать PDF файлы (например, если вы отправляете "сохранить документ в" test.pdf "на страницы, он будет генерировать PDF файл (но это работает только для Pages - мне нужна поддержка любого типа документа).
  • Пользовательский принтер. Я мог бы создать драйвер виртуального принтера, а затем использовать действие автомата, но мне не нравится идея запутать пользователя с дополнительным принтером в списке печати. ​​

Я надеюсь, что есть какой-то способ взаимодействия с активным приложением, как если бы пользователь выполнял следующие шаги:

  • Сделайте Cmd-P (открывает диалоговое окно печати)
  • Нажмите кнопку "PDF"
  • Выберите "Сохранить как PDF..." (второй элемент в меню)
  • Введите имя файла в диалоговом окне сохранения
  • Нажмите "Сохранить"

Если это лучший подход (это?), то реальная проблема заключается в следующем: как мне отправлять события пользовательского интерфейса во внешнее приложение (нажатия клавиш, события мыши, выбор меню)?

Обновление: Просто для уточнения одной точки: документы, которые мне нужно преобразовать в PDF, - это документы, созданные другими приложениями. Например, пользователь может выбрать документ Word или таблицу Numbers или чертеж OmniGraffle или веб-страницу. Общий знаменатель состоит в том, что в каждом из этих документов есть связанное приложение, и это приложение знает, как его печатать (и OSX знает, как отображать вывод печати в файл PDF).

Итак, образцы в Cocoa Dev Central не помогают, потому что они хотят создать PDF из моего приложения.

4b9b3361

Ответ 1

Я думаю, вы могли бы использовать applescript для открытия документа, а затем использовать applescript UI scripting для вызова меню печати.

Например:

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

Ответ 2

Взгляните на программу под названием CUPS-PDF

Это виртуальный принтер для OS X, который делает то, что делает метод "Сохранить как PDF" при печати через обычный принтер, за исключением каждого проходящего через него задания на печать, что приводит к выводу в формате PDF.

После его установки вы можете создать оболочку или AppleScripts с помощью команды lp.

Например, как только виртуальный принтер настроен, вы можете распечатать test.txt и автоматически сохранить его в формате pdf. Чтобы сделать это, используя AppleScript, вы должны использовать следующий код:

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

Приложение CUPS-PDF сохраняет весь вывод в /Users/Shared/CUPS -PDF. Я не уверен, что вы можете изменить этот путь, но вы можете получить файл в своем script и переместить его.

Однако есть несколько предостережений.

Во-первых, команда lp не может печатать файлы .doc. Я думаю, что есть и другие сторонние приложения, которые позволят вам это сделать.

Во-вторых, приложение CUPS-PDF показывает на панели "Принтер" системных настроек как дефис в своем имени, но CUPS показывает имя очереди как символ подчеркивания. Итак, в командной строке вам нужно обратиться к названию очереди CUPS, которое является CUPS_PDF с подчеркиванием.

Даже если вам не очень полезно создать script с помощью команды lp и по-прежнему хотят задействовать GUI-скрипты, а затем виртуальный принтер должен сэкономить вам несколько шагов.

Ответ 3

вы могли бы использовать чашки, подобные этому

    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 text item delimiters
        set AppleScript text item delimiters to "."
        set filename to text item 1 of filename
        set AppleScript 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

Ответ 4

Я создал псевдоним в bash для этого:

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

Ответ 5

Я набрал код ниже с помощью Automator (записывая действие, а затем перетаскивая конкретное действие из окна "Watch Me Do", чтобы получить Applescript). Если вы хотите распечатать PDF файл из приложения, отличного от Safari, вам может потребоваться выполнить один и тот же процесс и настроить этот Applescript в диалоговом окне "Печать", поскольку каждая программа может иметь другой графический интерфейс печати. ​​

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

# props to the following for helping me get frontmost window
# http://stackoverflow.com/info/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