我正在开发一个OSX项目,用户可以从中选择我需要生成PDF文档的文档集合(来自任何应用程序)。标准的“Macintosh打印”对话框有一个PDF按钮,其中包含许多与PDF相关的命令,包括“另存为PDF ...”。但是,我需要生成PDF文件而无需用户交互。理想情况下,我希望这适用于任何类型的文档。
这是我到目前为止所探讨的选项:
我希望有一些方法可以与活动应用程序进行交互,就像用户执行以下步骤一样:
如果这是最好的方法(是吗?)那么真正的问题是:如何将UI事件发送到外部应用程序(击键,鼠标事件,菜单选择)?
更新:只是澄清一点:我需要转换为PDF的文档是由其他应用程序创建的文档。例如,用户可能会选择Word文档或Numbers电子表格或OmniGraffle绘图或网页。共同点是这些文档中的每一个都有一个相关的应用程序,并且该应用程序知道如何打印它(OSX知道如何将打印输出呈现为PDF文件)。
因此,Cocoa Dev Central的样本没有帮助,因为它们是关于从我的应用程序生成PDF。
答案 0 :(得分: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
答案 1 :(得分:3)
查看名为CUPS-PDF
的程序它是OS X的虚拟打印机,它执行“另存为PDF”方法在通过普通打印机打印时所执行的操作,除了通过它的每个打印作业都会产生pdf输出。
安装后,您可以使用 lp 命令创建shell或AppleScripts。
例如,一旦设置了虚拟打印机,您就可以打印test.txt并将其自动另存为pdf。要使用AppleScript执行此操作,您将使用以下代码:
do shell script "lp -d CUPS_PDF test.txt"
CUPS-PDF应用程序将所有输出保存到/ Users / Shared / CUPS-PDF。我不确定您是否可以更改该路径,但您可以在脚本中检索文件并移动它。
但有几点需要注意。
首先, lp 命令无法打印.doc文件。我认为还有一些其他第三方应用程序可以让你这样做。
其次,CUPS-PDF应用程序在“系统偏好设置”的“打印机”面板中显示其名称中包含连字符,但CUPS将队列名称显示为具有下划线。因此,在命令行中,您需要引用CUPS队列名称,该名称是带有下划线的CUPS_PDF。
即使您没有发现通过 lp 命令构建脚本非常有用 并且仍然希望涉及GUI脚本,然后使用虚拟打印机可以为您节省一些步骤。
答案 2 :(得分: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
答案 3 :(得分:1)
我在bash中为此创建了一个别名:
convert2pdf() {
/System/Library/Printers/Libraries/convert -f "$1" -o "$2" -j "application/pdf"
}
答案 4 :(得分:0)
我在Automator的帮助下输入了以下代码(录制动作,然后将特定动作拖出“Watch Me Do”窗口以获取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