Pdf – How to batch print SWF files to PDF

batchbatch fileprint to pdfswf

I am using windows 7 X64.

I have installed Adobe Acrobat, so that I have a virtual PDF printer. I have also install the adobe flash player on the system.

I open the SWF file using the flash player, and from the flash player I can print the file to PDF.

I wonder if that is possible to repeat the process for a folder of SWF files.

During the "print" process, the PDF printer asks for a file name, which I want to use the file name from the SWF file. I hope this can be automated as well.

Thanks!

Best Answer

I was looking for the same thing. Well, I couldn't find any specific library to this job either. But at the very least we will be able to automate this process using GUI automation tools.

There are lots of libraries and standalone applications for this job. One that seems promising to me is Autoit.

But as a Python fan I found this amazing library called pywinauto and wrote the following script to convert my swf files:

"""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)

This method has its own limitations. For example you won't be able to use your computer during the conversion process as mouse and keyboard are controlled by the script. The script needs adjustments for individual computers. Also the GUI controlling process is supposed to be a lot slower than a CLI application designed to do the same job. However this is still far easier and faster than converting them manually.

P.S. I can't help but to mention Sikuli. Another amazing python library for GUI automation.

Update

The above method produces vector graphics, but if anyone is interested in rasterized .png files (which can be easily converted to pdf using freely available tools), they may want to try swfrender from swftools package. Currently, the latest stable binary version available for Windows is 0.9.0 (2009-07-21). But I recommend trying the development snapshot swftools-2013-04-09-1007.exe which offers some more options including the option -r which is used to adjust the resolution of the output file.

Related Question