# \[BUG\] Save pdf in perspective app

**URL:** <https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795>\
**Category:** Ignition Early Access\
**Created:** [August 27, 2019, 12:01pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795 "2019-08-27T12:01:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![joostjojo](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@joostjojo](https://forum.inductiveautomation.com/u/joostjojo)\
**Post date:** [August 27, 2019, 12:01pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/1 "2019-08-27T12:01:09Z")

</div>

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:

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

```

---

<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:** [August 27, 2019, 12:32pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/2 "2019-08-27T12:32:01Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![joostjojo](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@joostjojo](https://forum.inductiveautomation.com/u/joostjojo)\
**Post date:** [August 27, 2019, 12:37pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/3 "2019-08-27T12:37:50Z")

</div>

> [@pturmel](#):
>
> em.perspective.downloa

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](http://192.168.1.201:8088/data/perspective/client/Demo/pdf.worker.js%22,%22line) number":1,"column":1}

---

<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:** [August 27, 2019, 12:40pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/4 "2019-08-27T12:40:57Z")

</div>

> [@joostjojo](#):
>
> Unexpected token

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

---

<div class="post-metadata">

**Author:** ![wking](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/wking/32/21823_2.png) [@wking](https://forum.inductiveautomation.com/u/wking)\
**Post date:** [August 27, 2019, 3:31pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/5 "2019-08-27T15:31:36Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![wking](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/wking/32/21823_2.png) [@wking](https://forum.inductiveautomation.com/u/wking)\
**Post date:** [August 27, 2019, 3:37pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/6 "2019-08-27T15:37:24Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 27, 2019, 3:54pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/7 "2019-08-27T15:54:51Z")

</div>

> [@joostjojo](#):
>
> ###Fatal-{“msg”:“Uncaught Exception”,“errorMsg”:“Uncaught SyntaxError: Unexpected token \<”,“url”:“[http://192.168.1.201:8088/data/perspective/client/Demo/pdf.worker.js","line](http://192.168.1.201:8088/data/perspective/client/Demo/pdf.worker.js%22,%22line) number”:1,“column”:1}

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.

---

<div class="post-metadata">

**Author:** ![wking](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/wking/32/21823_2.png) [@wking](https://forum.inductiveautomation.com/u/wking)\
**Post date:** [August 27, 2019, 4:05pm UTC](https://forum.inductiveautomation.com/t/bug-save-pdf-in-perspective-app/27795/8 "2019-08-27T16:05:36Z")

</div>

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.
