web-dev-qa-db-ja.com

SWFファイルをPDFにバッチ印刷する方法は?

私はWindows7X64を使用しています。

Adobe Acrobatをインストールしたので、仮想PDFプリンターがあります。AdobeFlashPlayerもシステムにインストールしました。

フラッシュプレーヤーを使用してSWFファイルを開き、フラッシュプレーヤーからファイルをPDFに印刷できます。

SWFファイルのフォルダに対してこのプロセスを繰り返すことは可能かと思います。

「印刷」プロセス中に、PDFプリンターがファイル名を要求します。これは、SWFファイルのファイル名を使用します。これも自動化できることを願っています。

ありがとう!

4
Chen Stats Yu

私は同じものを探していました。ええと、私もこの仕事に特定のライブラリを見つけることができませんでした。ただし、少なくとも、GUI自動化ツールを使用してこのプロセスを自動化することができます。

このジョブには、多くのライブラリとスタンドアロンアプリケーションがあります。私にとって有望だと思われるのは Autoit です。

しかし、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アプリケーションよりもはるかに遅いと思われます。ただし、これは手動で変換するよりもはるかに簡単で高速です。

P.S. Sikuli と言わざるを得ません。 GUI自動化のためのもう1つの驚くべきpythonライブラリ。

更新

上記の方法ではベクターグラフィックが生成されますが、ラスタライズされた.pngファイル(無料で入手できるツールを使用してPDFに簡単に変換できます)に興味がある場合は、swfrender from swftools を試してみてください。 =パッケージ。現在、 最新 Windowsで使用可能な安定したバイナリバージョンは0.9.0(2009-07-21)です。ただし、出力ファイルの解像度を調整するために使用されるオプションswftools-2013-04-09-1007.exeを含む、いくつかのオプションを提供する開発スナップショット-rを試すことをお勧めします。

2
AXO

以下は、pywinautoを使用した私の貢献です。

私はインターネットエクスプローラーをブラウザーとして使用しました(したがって、インターネットエクスプローラーをswfファイルのデフォルトプログラムとして設定しました)。

また、Adobeacrobatを使用して印刷しました。 (印刷ダイアログのハンドルはほとんどのプログラムで似ているようですが、問題はないかもしれません)。 Adobeを使用していたため、印刷ダイアログのハンドルをから変更する必要がありました。

window.OK.click to window.Print.click(61行目)

また、以下の行(43行目)の値を変更する必要がある場合もあります。あなたの画面の解像度は私のものとは異なるかもしれないので。

browser_tab.click_input(coords =(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を反映してサポートするようにコードを更新しました(少なくとも私にとっては)。調べてみると、関数呼び出しはほとんど同じですが、キャメルケースからアンダースコアケースに変換されているだけです。

3
Samuel Thompson