Printing multiple Vision Client pages in one print job

I wish to print the pages (of type com.inductiveautomation.factorypmi.application.FPMIWindow) that I created in ignition in one single print job, as consecutive pages. Using createPrintJob, I am able to choose only one page per print job. Is there a straightforward way of achieving this by using Jython scripting?

No.

You’ll probably have to create your own print job; we don’t expose enough of JythonPrintJob to really do this.

Hello PGriffith,

Thank you for the quick response!

I took your advice and created a printerjob

book = Book()

P1 = system.gui.getWindow('P1')
P2 = system.gui.getWindow('P2')

printable1 = ComponentPrinter(P1, True, -1)
printable2 = ComponentPrinter(P2, True, -1)

job = PrinterJob.getPrinterJob()
pf = job.defaultPage()

# Create a letter sized piece of paper with one inch margins
paper = Paper()

# resize the paper and the imageable area
width = P1.getWidth()
height = P1.getHeight()
paper.setSize(width, height)
paper.setImageableArea(0, 0, width, height)

# set paper for the pageFormat
pf.setPaper(paper)

bk = Book()
bk.append(printable1, pf)
bk.append(printable2, pf)

job.setPageable(bk)
e = PrinterException()

if job.printDialog():
    try:
        job.print()
    except e:
        print "FAILED!"

This prints the PDF, but only the first page that is appended to the book. Explicitly specifying the number of pages while appending to the Book does not help.

I am stuck with this problem for weeks, it would be EPIC if I could find a solution!

Regards

Hm, at a glance that definitely seems correct. Does the book return the correct number of pages after you’ve appended both components?
https://docs.oracle.com/javase/7/docs/api/java/awt/print/Book.html#getNumberOfPages()

image
The number of pages returns exactly the number of printables (components) I append to the Book. This number is also visible at the print dialog. But the final document, that is printed using this logic, has only the first page.

Also, trying to print only the second page using the print dialog creates the xps file and then deletes it automatically.

Oh, boo. I didn’t notice; ComponentPrinter has a check at the beginning of its print method that aborts if the page index requested is not 0.

You’ll have to make your own ComponentPrinter-like; I tried monkey-patching print to always use page 0, but couldn’t get it to work:

from __future__ import print_function
from java.awt.print import Book, Paper, PrinterJob
from com.inductiveautomation.factorypmi.application.script.builtin.PrintUtilities import ComponentPrinter

book = Book()

P1 = system.gui.getWindow('pta')
P2 = system.gui.getWindow('treefont')

class MultipleComponentPrinter(ComponentPrinter):
	def print(self, graphics, format, pageIndex):
		ComponentPrinter.print(self, graphics, format, 0)

printable1 = MultipleComponentPrinter(P1, True, -1)
printable2 = MultipleComponentPrinter(P2, True, -1)

job = PrinterJob.getPrinterJob()
pf = job.defaultPage()

# Create a letter sized piece of paper with one inch margins
paper = Paper()

# resize the paper and the imageable area
width = P1.getWidth()
height = P1.getHeight()
paper.setSize(width, height)
paper.setImageableArea(0, 0, width, height)

# set paper for the pageFormat
pf.setPaper(paper)

bk = Book()
bk.append(printable1, pf)
bk.append(printable2, pf)

job.setPageable(bk)

if job.printDialog():
    job.print()
1 Like

When I try to print the multiple screen using this printerjob.
image

I am getting below error. Correct me where it went wrong

`Traceback (most recent call last):
File "event:actionPerformed", line 39, in
TypeError: integer required

at org.python.core.Py.TypeError(Py.java:236)
at org.python.core.Py.py2int(Py.java:1955)
at org.python.core.Py.py2int(Py.java:1946)
at org.python.proxies.__builtin__$MultipleComponentPrinter$14.print(Unknown Source)
at java.desktop/sun.print.RasterPrinterJob.printPage(Unknown Source)
at java.desktop/sun.print.RasterPrinterJob.print(Unknown Source)
at java.desktop/sun.print.RasterPrinterJob.print(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208)
at org.python.core.PyObject.__call__(PyObject.java:461)
at org.python.core.PyObject.__call__(PyObject.java:465)
at org.python.core.PyMethod.__call__(PyMethod.java:126)
at org.python.pycode._pyx63.f$0(<event:actionPerformed>:39)
at org.python.pycode._pyx63.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:788)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:297)
at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
at com.sun.proxy.$Proxy59.actionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)

Ignition v8.1.15 (b2022030114)
Java: Azul Systems, Inc. 11.0.14.1
`

Post the exact code you're using, because I have no idea what line 39 is.

from __future__ import print_function
from java.awt.print import Book, Paper, PrinterJob
from com.inductiveautomation.factorypmi.application.script.builtin.PrintUtilities import ComponentPrinter

book = Book()

P1 = system.gui.getWindow('Welcome')
P2 = system.gui.getWindow('Main Window')

class MultipleComponentPrinter(ComponentPrinter):
	def print(self, graphics, format, pageIndex):
		ComponentPrinter.print(self, graphics, format, 0)

printable1 = MultipleComponentPrinter(P1, True, -1)
printable2 = MultipleComponentPrinter(P2, True, -1)

job = PrinterJob.getPrinterJob()
pf = job.defaultPage()

# Create a letter sized piece of paper with one inch margins
paper = Paper()

# resize the paper and the imageable area
width = P1.getWidth()
height = P1.getHeight()
paper.setSize(width, height)
paper.setImageableArea(0, 0, width, height)

# set paper for the pageFormat
pf.setPaper(paper)

bk = Book()
bk.append(printable1, pf)
bk.append(printable2, pf)

job.setPageable(bk)

if job.printDialog():
    job.print()

Is it solved for you? same I am also facing I have 3 pages to print but only first page only printing for me.