Specify a printer when printing an Easy Chart

Is there a way to specify the printer when printing an Easy Chart without showing the printer selection dialog?

I have multiple windows, each having a single Easy Chart, that I want to print as a batch. I only want to prompt the user once for the printer to use.

I’ve figured out how to get a reference to the Java Print Service with the following code:

import javax.print printers = javax.print.PrintServiceLookup.lookupPrintServices(None, None) defaultPrinter = javax.print.PrintServiceLookup.lookupDefaultPrintService() printRequestAttributeSet = javax.print.attribute.HashPrintRequestAttributeSet() selectedPrinter = javax.print.ServiceUI.printDialog(None, 100, 100, printers, defaultPrinter, None, printRequestAttributeSet) if selectedPrinter != None: print selectedPrinter.getName() else: print "No printer selected"

I’ve written a class and some supporting functions that will allow me to print multiple charts as a single print job.

The basic process consists of printing the windows to image files, reloading them into imagebuffers, adding them to an object that implements the Java Printable interface, creating a printer job, displaying a printer dialog window, and then calling the printer job print function.

[code]#place this code in a module named app.printing
from java.awt.print import Printable

class MultiPageDoc(Printable):
def init(self):
self.__mDoc = []

def append(self, image):
	self.__mDoc.append(image)

def print(self, graphics, pageFormat, pageIndex):
	from java.awt.print import Printable
	from java.awt.print import PageFormat
	from java.awt import AlphaComposite
	from java.awt import RenderingHints

	if pageIndex < len(self.__mDoc):
		image = self.__mDoc[pageIndex]
		xScale = pageFormat.getImageableWidth() / image.getWidth()
		yScale = pageFormat.getImageableHeight() / image.getHeight()
		scale = min(xScale, yScale)
		if xScale < yScale:
			#width dictates scale, center vertically
			graphics.translate(pageFormat.getImageableY(), pageFormat.getImageableY() + (pageFormat.getImageableHeight() - (scale * image.getHeight())) / 2.0)
		else:
			#height dictates scale, center horizontally
			graphics.translate(pageFormat.getImageableY() + (pageFormat.getImageableWidth() - (scale * image.getWidth())) / 2.0, pageFormat.getImageableY())

		graphics.scale(scale, scale)
		graphics.setComposite(AlphaComposite.Src)
		graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
		graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)
		graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
		graphics.drawImage(image, 0, 0, None)

		return Printable.PAGE_EXISTS;
	else:
		return Printable.NO_SUCH_PAGE

def printMultiPageDoc(mDoc):
from fpmi.gui import messageBox, errorBox
from java.awt.print import PrinterJob
from javax.print import DocFlavor, PrintServiceLookup
from javax.print.attribute import HashPrintRequestAttributeSet
from javax.print.attribute.standard import OrientationRequested, JobName, Chromaticity

#create a print job and assign the multi-page document as the printable object
printJob = PrinterJob.getPrinterJob()
printJob.setPrintable(mDoc)

#specify a 'Printable' document flavor
docFlavor = DocFlavor('application/x-java-jvm-local-objectref', 'java.awt.print.Printable') 

#set desired attributes for a print service (i.e., printer)
attributeSet = HashPrintRequestAttributeSet()
attributeSet.add(OrientationRequested.LANDSCAPE)
attributeSet.add(Chromaticity.COLOR) #print in color
attributeSet.add(JobName("FPMI Multi-page Document", None)) #assign print job name

#locate a print service that will handle the desired document flavor and attributes
services = PrintServiceLookup.lookupPrintServices(docFlavor, attributeSet)
if len(services) > 0:
	#show a print dialog window so user can select the printer, set margins, set page orientation, etc.
	if printJob.printDialog(attributeSet):
		try:
			printJob.print(attributeSet)
			messageBox('Printing complete.')
		except:
			errorBox('An unexpected error was encountered while printing the multi-page document.')
	else:
		messageBox('Printing cancelled.')
else:
	errorBox('No printer with the necessary attributes and capable of handling a "Printable" document was found.')

[/code]I wanted to have more control when creating a temporary file so I created my own routine to get one.

[code]#place this code in a module named app.misc
def getTempFilename():
from java.lang.System import getenv, getProperty
from java.io import File
from os.path import join
from random import random

tmpPath = getenv('tmp')

if tmpPath == None:
	tmpPath = getenv('temp')

if tmpPath == None:
	tmpPath = getProperty("user.home")

tempFilename = join(tmpPath, ("fpmi%09d.jpg" % (999999999 * random())))
tempFile = File(tempFilename)
while tempFile.exists():
	tempFilename = join(tmpPath, ("fpmi%09d.jpg" % (999999999 * random())))
	tempFile = File(tempFilename)

tempFile = None
return tempFilename

[/code]
The following code is responsible for printing the charts to an image file, reloading them into an bufferimage, and adding the bufferimages to my MultiPageDoc:

[code]#place this code in a module named app.testing
def testPrintCharts():
from app.printing import MultiPageDoc, printMultiPageDoc
from app.misc import getTempFilename
from fpmi.gui import getWindow
from fpmi.print import printToImage
from java.awt.image import BufferedImage
from java.io import File
from javax.imageio import ImageIO
from os import unlink

chart = getWindow('Floating').rootContainer.getComponent('ChartContainer')

mDoc = MultiPageDoc()

for index in range(0, 2):
	#write window image to a random file, read it back into a buffered image, 
	#then append the buffered image to the multi-page document
	filename = getTempFilename()
	printToImage(chart, filename)
	file = File(filename);
	bufferedImage = ImageIO.read(file)
	unlink(filename)
	mDoc.append(bufferedImage)

printMultiPageDoc(mDoc)

[/code]In my test application I have one window name ‘Floating’. I open it and execute the following code in the script playground to print two copies of a single chart from the ‘Floating’ window:

import app.testing app.testing.testPrintCharts()

Hi,
Below code working in vision module. Can you please share code for Ignition Perspective module ( version 8.1.15 )?

Not possible in Perspective. Browser security prevents anything like this. The best you can do is use the reporting module to generate a PDF, then trigger its download. The user would have to take it from there.

Can you please share any solution for perspective(without using reporting module) print functionality?

Perspective is browser-based. Browsers do not permit code in a page to automatically print without user intervention. Browsers are also somewhat indeterminate as to page layout when printing from a scalable page, so there’s nothing at all like Vision’s ability to create print jobs.

You must print from the gateway, for which only the reporting module has native support.

Or you must download a file for the user to print, which is only relatively easy if a PDF. Only the reporting module has native PDF generation.

The only method in Ignition that permits native printing of a User Interface is in Vision. Sorry.

Thank you for providing the detailed information and instructions.