# Specify a printer when printing an Easy Chart

**URL:** <https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177>\
**Category:** Archived Topics\
**Created:** [August 14, 2011, 3:24am UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177 "2011-08-14T03:24:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![MickeyBob](https://avatars.discourse-cdn.com/v4/letter/m/e19adc/32.png) [@MickeyBob](https://forum.inductiveautomation.com/u/MickeyBob)\
**Post date:** [August 14, 2011, 3:24am UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/1 "2011-08-14T03:24:51Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![MickeyBob](https://avatars.discourse-cdn.com/v4/letter/m/e19adc/32.png) [@MickeyBob](https://forum.inductiveautomation.com/u/MickeyBob)\
**Post date:** [September 5, 2011, 1:28am UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/2 "2011-09-05T01:28:50Z")

</div>

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](http://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](http://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()`

---

<div class="post-metadata">

**Author:** ![sagar.iparkar](https://avatars.discourse-cdn.com/v4/letter/s/47e85d/32.png) [@sagar.iparkar](https://forum.inductiveautomation.com/u/sagar.iparkar)\
**Post date:** [September 2, 2022, 12:05pm UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/3 "2022-09-02T12:05:14Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 2, 2022, 12:35pm UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/4 "2022-09-02T12:35:35Z")

</div>

> [@sagar.iparkar](#):
>
> Perspective module

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.

---

<div class="post-metadata">

**Author:** ![sagar.iparkar](https://avatars.discourse-cdn.com/v4/letter/s/47e85d/32.png) [@sagar.iparkar](https://forum.inductiveautomation.com/u/sagar.iparkar)\
**Post date:** [September 5, 2022, 11:08am UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/5 "2022-09-05T11:08:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 5, 2022, 1:57pm UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/6 "2022-09-05T13:57:01Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sagar.iparkar](https://avatars.discourse-cdn.com/v4/letter/s/47e85d/32.png) [@sagar.iparkar](https://forum.inductiveautomation.com/u/sagar.iparkar)\
**Post date:** [September 7, 2022, 6:04am UTC](https://forum.inductiveautomation.com/t/specify-a-printer-when-printing-an-easy-chart/3177/8 "2022-09-07T06:04:31Z")

</div>

Thank you for providing the detailed information and instructions.
