Create PDF of Multiple Windows / Print all Windows of Project / Snapshot of Entire Project

We currently use a button component with a mouseClicked script to print the current window:

# window = system.gui.getWindow('Process')
job = system.print.createPrintJob(event.source.parent.parent.parent)
job.setMargins(0.5)
job.fitToPage = 1
job.orientation = system.print.LANDSCAPE
job.showPageFormat = 0
job.print()

Does anyone know a way to print multiple windows or more preferably create a PDF (snapshot) of multiple windows of a client? The goal is to create a snapshot of all the windows in the project

  1. You're going to need a hardcoded list of strings of the names of windows you want or use system.gui.getWindowNames - Ignition User Manual 8.1 - Ignition Documentation to get ALL the names if that is truly what you want to do.

  2. Iterating through your list of windows, you will need to open them (most likely with some appropriate parameters to avoid any red overlays) using system.nav.openWindow(windowName).

  3. Then you need to get and feed the the root container of the window to your system.print.createPrintJob with all the settings and then print it.

  4. You will probably need a pause in between doing each of these. I know time.sleep. is frowned upon (sorry Phil!) but this sounds like a one-shot operation so for the sake of being able to give you an answer that works, I would use it for now.

All together I think it would look like

allWindows = system.gui.getWindowNames() # Or hardcode your list if you only need a subset
for window in allWindows:
    win = system.nav.openWindow(window)
    rc = win.getRootContainer()
    # from here we can use your script
    job = system.print.createPrintJob(rc)
    job.setMargins(0.5)
    job.fitToPage = 1
    job.orientation = system.print.LANDSCAPE
    job.showPageFormat = 0
    job.print()
    time.sleep(10)

Only catch I can think is some windows are needed and some are now in which case I would include a variable that is a dictionary of your window names and desired parameters. In that case you can do something like

allWindows = system.gui.getWindowNames() # Or hardcode your list if you only need a subset
windowParams = {'someWindow':{'someParam':'someValue'}}
for window in allWindows:
    try:
        params = windowParams[window]
    except KeyError:
        params={}
    win = system.nav.openWindow(window, params)
    rc = win.getRootContainer()
    # from here we can use your script
    job = system.print.createPrintJob(rc)
    job.setMargins(0.5)
    job.fitToPage = 1
    job.orientation = system.print.LANDSCAPE
    job.showPageFormat = 0
    job.print()
    time.sleep(10)

I have not tested this at all but I think this should be ok and the structure is basically right. You may need to adjust the sleep depending on how quickly or slowly your windows load. Realistically if this is something you run often you probably want to use something other than time.sleep.

1 Like

I have this running off of a button component. This is something we would do probably do on a quarterly or monthly basis.

Ok great give it a try and let me know how it goes.

1 Like

You can do this via direct access to Java's print system, to create a multi-page single job. IA's script function is a wrapper for a single component or window.

When working directly with printing operations, the windows do not need to be "on top", just open.

This is Vision. sleep() will hog the UI thread and your windows won't be able to open. Open them all without delay, then use .invokeLater() to run the function that actually prints.

2 Likes

You can also cause windows to paint to an image buffer, and then save those images.

1 Like

You learn something new everyday.

When I do my testing with scripts and I need to do a rc=win.getRootContainer() in designer in script console to poke around a window, it does need to be be open which I use system.nav.openWindow() for in my own scripts to make it work. So I just assumed similar.

1 Like

Pssst! @bkarabinchak.psi ! Whenever (almost) you think to use .sleep(), you are screwing up. Especially in Vision. Apologizing to me doesn't fix it. Apologize to those who get in a bind by taking that advice. :frowning_face:

I still use it in the occasional one shot functions :upside_down_face: that is what this sounded like and in occasional uses hasn't ruined the overall functionality of the script so I didn't have reason to think so here. But I guess that's why you get a personal shoutout at ICC and I don't :joy:

Thank you Phil!

This is what we have so far but it appears to give a print pop up for every window (Versus 1 popup that allows to save as one PDF.
Would also like to specify a subset of windows vs all if possible.

import system
allWindows = system.gui.getWindowNames()
for window in allWindows:
win = system.nav.openWindow(window)
rc = win.getRootContainer()
# from here we can use your script
job = system.print.createPrintJob(rc)
job.setMargins(0.5)
job.fitToPage = 1
job.orientation = system.print.LANDSCAPE
job.showPageFormat = 0
printjob = job.print()
system.util.invokeLater(printjob)

For a subset of windows change the allWindows variable to a list of string names of the windows you care about.

1 Like

This can only do one window or component at a time. I solved this back in the FactoryPMI days to do custom multipage "reports". Buried somewhere in my archives. But I think I started here:

javax.print

Hmmm: Or maybe java.awt.print. Pageable looks familiar.

1 Like