3

Я использую Windows 7 X64.

Я установил Adobe Acrobat, чтобы у меня был виртуальный принтер PDF. Я также установил Adobe Flash Player в системе.

Я открываю SWF-файл с помощью флеш-плеера, и из флеш-плеера я могу распечатать файл в PDF.

Интересно, можно ли повторить процесс для папки SWF-файлов.

Во время процесса "печати" принтер PDF запрашивает имя файла, для которого я хочу использовать имя файла из SWF-файла. Я надеюсь, что это также может быть автоматизировано.

Спасибо!

3 ответа3

3

Ниже мой вклад также с использованием Pywinauto.

Я использовал Internet Explorer в качестве браузера (поэтому установите Internet Explorer в качестве программы по умолчанию для SWF-файлов), так как я нашел, что он загружает SWF-файлы быстрее всего (я знаю ... странно верно).

Я также использовал Adobe Acrobat для печати. (кажется, что дескриптор диалога печати похож на большинство программ, хотя у вас могут не возникнуть проблемы). Поскольку я использовал Adobe, мне пришлось изменить свой дескриптор диалогового окна печати с

окно.ОК. Нажмите на окно.Print.click (в строке 61)

Также вам может потребоваться изменить значения для строки ниже (строка 43). Поскольку разрешение экрана может отличаться от моего.

browser_tab.click_input(ords =(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.

2

Я искал то же самое. Ну, я не мог найти какой-либо конкретной библиотеки для этой работы. Но, по крайней мере, мы сможем автоматизировать этот процесс с помощью инструментов автоматизации графического интерфейса.

Есть много библиотек и автономных приложений для этой работы. То, что мне кажется многообещающим, это 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, предназначенное для выполнения той же работы. Однако это все еще намного проще и быстрее, чем конвертировать их вручную.

PS Не могу не упомянуть Сикули. Еще одна удивительная библиотека Python для автоматизации графического интерфейса.

Обновить

Вышеупомянутый метод создает векторную графику, но если кому-то интересны растеризованные файлы .png (которые можно легко преобразовать в pdf с помощью свободно доступных инструментов), они могут попробовать swfrender из пакета swftools . В настоящее время последняя стабильная бинарная версия, доступная для Windows, - 0.9.0 (2009-07-21). Но я рекомендую попробовать снимок разработки swftools-2013-04-09-1007.exe который предлагает еще несколько опций, включая опцию -r которая используется для настройки разрешения выходного файла.

-2

Я нашел альтернативный способ сделать это:

  1. Используйте "Xilisoft convertor" для конвертации SWF в JPG (возможно пакетное преобразование)
  2. Используйте онлайн конвертеры, чтобы объединить все JPG в PDF

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .