How to programmatically generate a PDF from any document on OSX?

Denis Hennessy picture Denis Hennessy · Nov 9, 2008 · Viewed 7.9k times · Source

I'm working on a project for OSX where the user can pick a collection of documents (from any application) which I need to generate PDF's from. The standard Macintosh Print dialog has a PDF button which has a number of PDF-related commands including "Save as PDF...". However, I need to generate the PDF file without requiring user interactions. I ideally want this to work with any type of document.

Here's the options I've explored so far:

  • Automator actions. There's a PDF library for Automator but it provides actions for working with PDF files, not generating them. There's a Finder action for printing any file but only to a real printer.
  • AppleScript. Some applications have the ability to generate PDF files (for instance, if you send 'save doc in "test.pdf"' to Pages it will generate a PDF (but this only works for Pages - I need support for any type of document).
  • Custom Printer. I could create a virtual printer driver and then use the automator action but I don't like the idea of confusing the user with an extra printer in the print list.

My hope is that there's some way to interact with the active application as if the user was carrying out the following steps:

  1. Do Cmd-P (opens the print dialog)
  2. Click the "PDF" button
  3. Select "Save as PDF..." (second item in menu)
  4. Type in filename in save dialog
  5. Click "Save"

If that's the best approach (is it?) then the real problem is: how do I send UI Events to an external application (keystrokes, mouse events, menu selections) ?

Update: Just to clarify one point: the documents I need to convert to PDF are documents that are created by other applications. For example, the user might pick a Word document or a Numbers spreadsheet or an OmniGraffle drawing or a Web Page. The common denominator is that each of these documents has an associated application and that application knows how to print it (and OSX knows how to render print output to a PDF file).

So, the samples at Cocoa Dev Central don't help because they're about generating a PDF from my application.

Answer

Timour picture Timour · Nov 10, 2008

I think you could use applescript to open a document and then use applescript UI scripting to invoke print menu.

For example :

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