我正在使用 Windows 7 X64。
我已经安装了 Adobe Acrobat,这样我就有了虚拟 PDF 打印机。我还在系统上安装了 Adobe Flash Player。
我使用 Flash 播放器打开 SWF 文件,然后从 Flash 播放器中我将文件打印为 PDF。
我想知道是否可以对 SWF 文件夹重复该过程。
在“打印”过程中,PDF 打印机会要求输入文件名,我希望使用 SWF 文件中的文件名。我希望这也可以自动化。
谢谢!
答案1
我也一直在寻找同样的东西。好吧,我也找不到任何特定的库来完成这项工作。但至少我们能够使用 GUI 自动化工具来自动化这个过程。
有很多库和独立应用程序可以完成这项工作。我认为比较有希望的一个是奥图伊特。
但作为一名 Python 粉丝,我发现了一个很棒的库,叫做pywinauto并编写了以下脚本来转换我的 swf 文件:
"""Convert all swf files in this directory to a pdf file using Firefox.
Note that some parameters in this script need to be adjusted according to
user's printer setup, screen resolution, etc.
Documentation of pywinauto:
* https://pywinauto.github.io/docs/contents.html
An example script using pywinauto:
* https://github.com/vsajip/pywinauto/blob/master/examples/SaveFromFirefox.py
"""
import re
import os
import warnings
import webbrowser
from time import sleep
from functools import partial
import pywinauto as pwa
from pywinauto.application import Application
def sendkey_escape(string):
"""Escape `+ ^ % ~ { } [ ] ( )` by putting them within curly braces.
Refer to sendkeys' documentation for more info:
* https://github.com/zvodd/sendkeys-py-si/blob/master/doc/SendKeys.txt
(Could not open the original site: rutherfurd.net/python/sendkeys/ )
"""
return re.sub(r'([+^%~{}\[\]()])', r'{\1}', string)
# Using 32-bit python on 64-bit machine? Will get the following warning a lot:
# "UserWarning: 64-bit application should be automated using 64-bit Python
# (you use 32-bit Python)"
# Limit this warnings to only show once.
# The following line does not work as expected. See
# github.com/pywinauto/pywinauto/issues/125
warnings.filterwarnings(
'once', message=r'.*64-bit application should.*', category=UserWarning
)
# Assume Firefox is already open.
app = Application().connect(title_re=".*Firefox")
firefox = app.MozillaFireFox.GeckoFPSandboxChildWindow
filenames = os.listdir()
for filename in filenames:
if not filename.endswith('.swf'):
continue
pdfname = filename[:-3] + 'pdf'
if pdfname in filenames:
# Already there!
continue
# Assume the default application to open swf files is Firefox.
webbrowser.open(filename)
firefox.SetFocus()
firefox.Wait('exists ready', timeout=5)
firefox.RightClickInput(coords=(200, 200))
firefox.Wait('ready', timeout=10)
# Click "print" from the rightclick menu.
firefox.ClickInput(coords=(210, 320))
pwa.timings.WaitUntilPasses(
timeout=10,
retry_interval=1,
func=partial(app.Connect, title='Print'),
exceptions=pwa.findwindows.WindowNotFoundError,
)
app.Print.Wait('ready active', 5)
# The printing process depends on the default printer being used.
app.Print.OK.Click()
app.Print.WaitNot('exists', timeout=5)
pwa.timings.WaitUntilPasses(
timeout=10,
retry_interval=1,
func=partial(app.Connect, title='Save As'),
exceptions=pwa.findwindows.WindowNotFoundError,
)
# Be wary that some characters such as "%" don't work correctly in Save As
# dialogs. This code does not handle such awkwardness of MS Windows.
app.SaveAS.ComboBox.SetFocus().TypeKeys(
sendkey_escape(os.getcwd() + '\\' + pdfname), with_spaces=True
)
app.SaveAS.Save.Click()
firefox.Wait('exists ready', timeout=5)
# Focuse is lost to flash (bugzilla: 78414). Use mouse to close the tab.
firefox.ClickInput(coords=(418, 16), absolute=True)
firefox.WaitNot("exists", timeout=5)
这种方法有其自身的局限性。例如,在转换过程中您将无法使用计算机,因为鼠标和键盘由脚本控制。脚本需要针对各个计算机进行调整。此外,GUI 控制过程应该比设计用于执行相同工作的 CLI 应用程序慢得多。但是,这仍然比手动转换更容易、更快。
PS 我忍不住要提一下西库利. 另一个用于 GUI 自动化的出色的 Python 库。
更新
上述方法生成的是矢量图形,但如果有人对栅格化的 .png 文件感兴趣(可以使用免费工具轻松转换为 pdf),他们可能想swfrender
尝试工具包。目前,最新的适用于 Windows 的稳定二进制版本是 0.9.0 (2009-07-21)。但我建议尝试开发快照,它提供了更多选项,包括用于调整输出文件分辨率的swftools-2013-04-09-1007.exe
选项。-r
答案2
以下是我使用 pywinauto 做出的贡献。
我使用 Internet Explorer 作为浏览器(因此将 Internet Explorer 设置为 swf 文件的默认程序),因为我发现它加载 swf 文件的速度最快(我知道……很奇怪吧)。
我还使用 Adobe Acrobat 进行打印。(不过,大多数程序的打印对话框句柄似乎都类似,因此您可能不会遇到麻烦)。因为我使用了 Adobe,所以我必须将打印对话框的句柄从
window.OK.click 到 window.Print.click (第 61 行)
您可能还需要更改下面一行(第 43 行)的值。因为您的屏幕分辨率可能与我的不同。
browser_tab.click_input(坐标=(1440,2060))
如果解释得不好,请原谅,另外因为它是 python,请检查下面代码中的缩进是否正确。
import sys
import re
import os
import warnings
import webbrowser
from time import sleep
import pywinauto as pwa
from pywinauto.application import Application
from pywinauto.keyboard import SendKeys
def sendkey_escape(string):
"""Escape `+ ^ % ~ { } [ ] ( )` by putting them within curly braces.
Refer to sendkeys' documentation for more info:
* https://github.com/zvodd/sendkeys-py-si/blob/master/doc/SendKeys.txt
(Could not open the original site: rutherfurd.net/python/sendkeys/ )
"""
return re.sub(r'([+^%~{}\[\]()])', r'{\1}', string)
warnings.filterwarnings(
'once', message=r'.*64-bit application should.*', category=UserWarning
)
filenames = os.listdir(os.getcwd())
app = Application()
for filename in filenames:
#pwa.timings.Timings.Slow()
if not filename.endswith('.swf'):
continue
pdfname = filename[:-3] + 'pdf'
if pdfname in filenames:
# Already there!
continue
# Assume the default application to open swf files is browser_tab.
webbrowser.open(filename)
sleep(2)
app.connect(title_re='.*Explorer', class_name='IEFrame')
browser_tab = app.IEFrame
browser_tab.wait('active')
browser_tab.set_focus()
#below to enable activex controls
browser_tab.click_input(coords=(1440, 2060))
sleep(2)
browser_tab.right_click_input(coords=(500, 500))
# Click "print" from the rightclick menu.
browser_tab.click_input(coords=(540, 645))
pwa.timings.wait_until_passes(
20,
0.5,
browser_tab[u'Print'].Exists,
pwa.findwindows.WindowNotFoundError
)
app2 = Application().connect(title=u'Print')
pwa.timings.Timings.Defaults()
window = app2.Print
window.wait('ready')
button = window.Print
button.Click()
pwa.timings.wait_until_passes(
20,
0.5,
browser_tab[u'Save PDF File As'].Exists,
pwa.findwindows.WindowNotFoundError
)
app3 = Application().connect(title=u'Save PDF File As', class_name='#32770')
window = app3.Dialog
combobox = window[u'4']
combobox.set_focus().type_keys(sendkey_escape(os.getcwd() + '\\' + pdfname), with_spaces=True)
window.Save.Click()
pwa.timings.wait_until_passes(
20,
0.5,
app[u'Creating Adobe PDF'].Exists,
pwa.findwindows.WindowNotFoundError
)
app4 = app.connect(title=u'Creating Adobe PDF', class_name='#32770')
window3 = app4.Dialog
window3.wait_not('active',20,1)
browser_tab.Close()
我使用 SWAPY 来帮助获取每个窗口的控件标识符。但是 SWAPY 使用的是旧代码(尽管仍然非常有用),所以我更新了代码以反映和支持 pywinauto 的当前版本(至少对我来说是这样)。如果你查看它,函数调用大致相同,只是从 camelcase 转换为 underscore_case。
答案3
我找到了另一种方法来做到这一点:
- 使用“Xilisoft 转换器”将 swf 转换为 jpg(可以批量转换)
- 使用在线转换器将所有 jpg 转换为 pdf