如何将 SWF 文件批量打印为 PDF?

如何将 SWF 文件批量打印为 PDF?

我正在使用 Windows 7 X64。

我已经安装了 Adob​​e Acrobat,这样我就有了虚拟 PDF 打印机。我还在系统上安装了 Adob​​e 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 文件的速度最快(我知道……很奇怪吧)。

我还使用 Adob​​e Acrobat 进行打印。(不过,大多数程序的打印对话框句柄似乎都类似,因此您可能不会遇到麻烦)。因为我使用了 Adob​​e,所以我必须将打印对话框的句柄从

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

我找到了另一种方法来做到这一点:

  1. 使用“Xilisoft 转换器”将 swf 转换为 jpg(可以批量转换)
  2. 使用在线转换器将所有 jpg 转换为 pdf

相关内容