2008-11-09 78 views
18

我正在开发一个OSX项目,用户可以从中选择需要生成PDF的文档集合(来自任何应用程序)。标准的Macintosh打印对话框有一个PDF按钮,其中有许多与PDF相关的命令,包括“另存为PDF ...”。但是,我需要生成PDF文件而无需用户交互。我理想的是希望这可以用于任何类型的文档。如何以编程方式从OSX上的任何文档生成PDF?

这里是我到目前为止探索的选项:

  • Automator动作。有一个用于Automator的PDF库,但它提供了处理PDF文件的操作,而不是生成它们。 Finder有一个打印任何文件的动作,但只能打印一个真实的打印机。
  • AppleScript。某些应用程序可以生成PDF文件(例如,如果您将'doc.pdf'中的doc保存到Pages中,它将生成PDF(但这仅适用于Pages) - 我需要支持任何类型的文档) 。
  • 自定义的打印机。我可以创建一个虚拟打印机驱动程序,然后使用Automator的行动,但我不喜欢在打印列表中的一个额外的打印机混淆用户的想法。

我希望有一些方法可以与活动应用程序交互,就好像用户正在执行以下步骤一样:

  1. Do Cmd-P(打开打印对话框)
  2. 点击 “PDF” 按钮
  3. 选择 “另存为PDF ...”(在菜单的第二项)
  4. 键入文件名在保存对话框
  5. 点击 “保存”

如果这是最好的方法(是吗?),那么真正的问题是:我如何将UI事件发送到外部应用程序(击键,鼠标事件,菜单选择)?

更新:我只想澄清一点:我需要转换为PDF文件是由其他应用创建的文档。例如,用户可能会选择Word文档或Numbers电子表格或OmniGraffle绘图或Web页面。共同点是每个文档都有一个关联的应用程序,并且该应用程序知道如何打印它(并且OSX知道如何将打印输出呈现为PDF文件)。

因此,可可开发中心的样本并没有帮助,因为它们是从我的应用程序生成PDF。

回答

6

我想你可以用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 
+0

谢谢!那正是我正在寻找的指针。 – 2008-11-10 09:51:06

+2

-1这似乎是一个好方法,如果你打开Safari浏览器中的一个文件,但我敢肯定,你不想正确的代码为每一种可能的应用 – mcgrailm 2010-12-13 15:19:50

0

我输入了下面的Automator的援助代码(记录的动作,然后拖动具体行动出了“看我做”窗口,以获得AppleScript的)。如果您想从Safari以外的应用程序中打印PDF,则可能需要运行相同的过程,并围绕“打印”对话框调整此Applescript,因为每个程序都可能具有不同的打印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

看看一个叫程序CUPS-PDF

这是OS X的虚拟打印机它执行“另存为PDF”的方法做什么时,通过除穿过每个打印作业的普通打印机打印它会产生一个pdf输出。

安装完成后,您可以使用lp命令创建shell或AppleScript。

例如,一旦虚拟打印机的设置,你可以打印的test.txt,并自动保存为PDF。要做到这一点使用一个AppleScript你可以使用下面的代码:

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

的CUPS-PDF应用中的所有输出保存到/用户/共享/ CUPS-PDF。我不确定您是否可以更改该路径,但可以在脚本中检索该文件并将其移动。

有几个注意事项虽然。

首先,LP命令不能打印.doc文件。我认为还有一些其他的第三方应用程序可以让你做到这一点。

二,CUPS-PDF应用程序显示在系统偏好设置的打印机窗格为在它的名字,但CUPS连字符显示队列名称为具有下划线。因此,在命令行上,您需要使用下划线参考CUPS_PDF的CUPS队列名称。

即使你不觉得它是非常有用的,以通过LP命令 建立一个脚本,还是要涉及到GUI脚本然后有一个虚拟打印机应该节省一些步骤。

1

你可以使用杯子这样

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

我已经创建了在bash别名此:

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