[BUG] Save pdf in perspective app

Hello,

I am able to save an pdf to my computer or phone with perspective.
However this only works when perspective is opened in a browser (also on phone).
But with the perspective app it does not do anything at all.
When I do it through the app I get the following error in the logs on the gateway:

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File “”, line 20, in runAction at java.desktop/javax.print.ServiceUI.printDialog(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) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: services must be non-null and non-empty

at org.python.core.Py.JavaError(Py.java:552)

at org.python.core.Py.JavaError(Py.java:543)

at org.python.core.PyReflectedFunction.call(PyReflectedFunction.java:190)

at org.python.core.PyReflectedFunction.call(PyReflectedFunction.java:206)

at org.python.core.PyObject.call(PyObject.java:450)

at org.python.core.PyObject.call(PyObject.java:454)

at org.python.pycode._pyx16310.runAction$1(:23)

at org.python.pycode._pyx16310.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:171)

at org.python.core.PyBaseCode.call(PyBaseCode.java:308)

at org.python.core.PyFunction.function___call__(PyFunction.java:471)

at org.python.core.PyFunction.call(PyFunction.java:466)

at org.python.core.PyFunction.call(PyFunction.java:456)

at org.python.core.PyFunction.call(PyFunction.java:451)

at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:776)

at com.inductiveautomation.ignition.common.script.ScriptManager$ScriptFunctionImpl.invoke(ScriptManager.java:894)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$AutoRecompilingScriptFunction.invoke(ProjectScriptLifecycle.java:574)

at com.inductiveautomation.perspective.gateway.script.ScriptFunctionHelper.invoke(ScriptFunctionHelper.java:87)

at com.inductiveautomation.perspective.gateway.action.ScriptAction.runAction(ScriptAction.java:65)

at com.inductiveautomation.perspective.gateway.action.ActionDecorator.runAction(ActionDecorator.java:18)

at com.inductiveautomation.perspective.gateway.action.SecuredAction.runAction(SecuredAction.java:51)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.lambda$call$0(ActionCollection.java:257)

at com.inductiveautomation.perspective.gateway.api.LoggingContext.mdc(LoggingContext.java:54)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:246)

at com.inductiveautomation.perspective.gateway.model.ActionCollection$ActionSequence$ExecuteActionsTask.call(ActionCollection.java:215)

at com.inductiveautomation.perspective.gateway.threading.BlockingTaskQueue$TaskWrapper.run(BlockingTaskQueue.java:154)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

at java.base/java.util.concurrent.FutureTask.run(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.base/java.lang.Thread.run(Unknown Source)

Caused by: org.python.core.PyException: Traceback (most recent call last): File “”, line 20, in runAction at java.desktop/javax.print.ServiceUI.printDialog(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) java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: services must be non-null and non-empty

… 31 common frames omitted

Caused by: java.lang.IllegalArgumentException: services must be non-null and non-empty

at java.desktop/javax.print.ServiceUI.printDialog(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:188)

… 28 common frames omitted

The script I run to print is:

	from java.awt import Robot, Rectangle
	from java.io import File, ByteArrayOutputStream
	from javax.print import Doc, DocFlavor, DocPrintJob, PrintService, PrintServiceLookup, SimpleDoc, ServiceUI 
	from javax.print.attribute import HashPrintRequestAttributeSet, HashDocAttributeSet
	from javax.print.attribute.standard import Copies, OrientationRequested
	DocAttributeSet = HashDocAttributeSet()
	printJobAttributeSet = HashPrintRequestAttributeSet()
	rintJobAttributeSet = HashPrintRequestAttributeSet()
	printJobAttributeSet.add(Copies(1))
	printJobAttributeSet.add(OrientationRequested.LANDSCAPE)
	
	file = 'Report.pdf'
	bytesArray = system.report.executeReport(path="Report", project="Demo", fileType="pdf")
	system.perspective.download(file, bytesArray)
	doc=SimpleDoc(bytesArray,DocFlavor.BYTE_ARRAY.PDF,DocAttributeSet)
	services = PrintServiceLookup.lookupPrintServices( DocFlavor.BYTE_ARRAY.PDF, None )
	service = ServiceUI.printDialog(None,100,100,services,PrintServiceLookup.lookupDefaultPrintService(),None, printJobAttributeSet)
	
	job=service.createPrintJob()
	job.print(doc,printJobAttributeSet)`Preformatted text`
type or paste code here

You have printing operations mixed into the same script as the download. Those operations certainly wouldn’t work in a perspective app, as that script runs on the gateway. Try getting rid of everything in the script after the system.perspective.download() line.

Thanks, I removed that part.
However it's still not working.
This time i get this in my logs:

###Fatal-{"msg":"Uncaught Exception","errorMsg":"Uncaught SyntaxError: Unexpected token <","url":"http://192.168.1.201:8088/data/perspective/client/Demo/pdf.worker.js","line number":1,"column":1}

This looks like the real bug. If IA staff doesn't respond to this topic, you might want to report it to support directly.

1 Like

If you don’t mind please respond with solution. I’ve been trying to get this script to work for sometime.

https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/print-reports-from-perspective

1 Like

I would suggest getting in contact with support so they can figure out what's going on. I ran a simple test, and I was able to pass the output of system.report.executeReport into system.perspective.download just fine - it just downloaded the file directly. A better print function that gives control to the user would be nice, but is likely hard to do with the way browsers sandbox things - but I know is on our list of things to work on.

That is the solution I had to settle on. Letting clients download the file. And print it like you would any other downloaded thing. Getting them to navigate to their downloads folder and clearing it out every so often is a near impossible feat. Also have had problems while execution and distributing while they have the previous downloaded report still open.