# Script on Download button on Report Viewer in Perspective

**URL:** <https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862>\
**Category:** Ignition\
**Tags:** perspective, scripting\
**Created:** [December 30, 2020, 5:29pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862 "2020-12-30T17:29:56Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![awarunek187](https://avatars.discourse-cdn.com/v4/letter/a/a5b964/32.png) [@awarunek187](https://forum.inductiveautomation.com/u/awarunek187)\
**Post date:** [December 30, 2020, 5:29pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/1 "2020-12-30T17:29:56Z")

</div>

I would like to add ‘save as’ functionality through a script on the download button on the report viewer for Perspective. Which event would I place my script on?

---

<div class="post-metadata">

**Author:** ![awarunek187](https://avatars.discourse-cdn.com/v4/letter/a/a5b964/32.png) [@awarunek187](https://forum.inductiveautomation.com/u/awarunek187)\
**Post date:** [December 30, 2020, 5:38pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/2 "2020-12-30T17:38:36Z")

</div>

I found that the issue is resolved with my browser settings. However, I would also like to add other scripting functionality to save certain values, I incorporate into the Reports parameters, into a table in my DB. Is this possible on one of the events?

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [December 30, 2020, 6:43pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/3 "2020-12-30T18:43:11Z")

</div>

There’s no way currently to hook into a user pressing the download button, but you can use any of the regular events to manage this. What I recommend for now is a separate button from the Report Viewer to perform this database update.

---

<div class="post-metadata">

**Author:** ![awarunek187](https://avatars.discourse-cdn.com/v4/letter/a/a5b964/32.png) [@awarunek187](https://forum.inductiveautomation.com/u/awarunek187)\
**Post date:** [December 30, 2020, 6:48pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/4 "2020-12-30T18:48:04Z")

</div>

Thank you very much. That is what I figured. Do you know the right script to use on a button to send the report on the report viewer to a DB? I am currently using a file upload button elsewhere with this script to do it:

```
# Grab the file name and data
filename = event.file.name
filedata = event.file.getBytes()
     
# Use a query to insert the file
query = "INSERT INTO files (filename, filedata) VALUES(?, ?)"
args = [filename, filedata]
system.db.runPrepUpdate(query, args)

```

However, this just grabs a file from a local directory and uploads it. I just want a button that sends the report viewer to a pdf to my ‘files’ table in my DB.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [December 30, 2020, 9:20pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/5 "2020-12-30T21:20:32Z")

</div>

The button won’t have access to a `file` object as part of the event; `onClick` and `actionPerformed` Events contain an empty `event` object.

You’ll need to look into using [system.file.readFileAsBytes(filepath)](https://docs.inductiveautomation.com/display/DOC80/system.file.readFileAsBytes) where you construct the filepath argument from `ReportViewer.props.source`. Something like this:

```auto
filename = self.getSibling('ReportViewer').props.source
filepath = "C:\\path\to\file\" + filename
filedata = system.file.readFileAsBytes(filepath)
     
# Use a query to insert the file
query = "INSERT INTO files (filename, filedata) VALUES(?, ?)"
args = [filename, filedata]
system.db.runPrepUpdate(query, args)

```

---

<div class="post-metadata">

**Author:** ![awarunek187](https://avatars.discourse-cdn.com/v4/letter/a/a5b964/32.png) [@awarunek187](https://forum.inductiveautomation.com/u/awarunek187)\
**Post date:** [December 30, 2020, 9:24pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/6 "2020-12-30T21:24:44Z")

</div>

I ended up doing this script on the button:

today = system.date.now()

```
# Grab the file name and data
filename = "QCF-1168" + system.date.format(today, "yy/MM/dd")
overrides = {"SkeletonNumber":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.SkeletonNumber, 
				"Face1Grid10":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid10,
				"Face1Grid9":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid9,
				"Face1Grid8":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid8,
				"Face1Grid7":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid7,
				"Face1Grid6":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid6,
				"Face1Grid5":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid5,
				"Face1Grid4":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid4,
				"Face1Grid3":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid3,
				"Face1Grid2":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid2,
				"Face1Grid1":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face1Grid1,
				"Face2Grid10":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid10,
				"Face2Grid9":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid9,
				"Face2Grid8":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid8,
				"Face2Grid7":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid7,
				"Face2Grid6":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid6,
				"Face2Grid5":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid5,
				"Face2Grid4":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid4,
				"Face2Grid3":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid3,
				"Face2Grid2":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid2,
				"Face2Grid1":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face2Grid1,
				"Face3Grid10":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid10,
				"Face3Grid9":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid9,
				"Face3Grid8":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid8,
				"Face3Grid7":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid7,
				"Face3Grid6":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid6,
				"Face3Grid5":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid5,
				"Face3Grid4":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid4,
				"Face3Grid3":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid3,
				"Face3Grid2":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid2,
				"Face3Grid1":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face3Grid1,
				"Face4Grid10":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid10,
				"Face4Grid9":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid9,
				"Face4Grid8":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid8,
				"Face4Grid7":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid7,
				"Face4Grid6":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid6,
				"Face4Grid5":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid5,
				"Face4Grid4":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid4,
				"Face4Grid3":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid3,
				"Face4Grid2":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid2,
				"Face4Grid1":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.Face4Grid1,
				"FuelAssemblyNum":self.parent.parent.getChild("FlexContainer").getChild("FlexContainer_0").getChild("ReportViewer").props.params.FuelAssemblyNum
				}
filedata = system.report.executeReport(path="FormWEC", project="Perspective_Training", parameters=overrides, fileType="pdf")
     
# Use a query to insert the file
query = "INSERT INTO files (filename, filedata) VALUES(?, ?)"
args = [filename, filedata]
system.db.runPrepUpdate(query, args)

```

I have a lot of parameters on my report.

The next thing that I am trying to do is display a PDF from my DB, in the PDF viewer in Perspective, on a selectedRow from my table. I guess this is done somehow with the WebDev module and setting a source as python? I am looking into it at the moment. If you have any thoughts that could help me, I would greatly appreciate it.

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [December 30, 2020, 9:27pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/7 "2020-12-30T21:27:20Z")

</div>

> [@awarunek187](#):
>
> I guess this is done somehow with the WebDev module

This is the best option, yes. You should only need to use a File Resource though - I don't know why you'd use a Python resource for this.

---

<div class="post-metadata">

**Author:** ![awarunek187](https://avatars.discourse-cdn.com/v4/letter/a/a5b964/32.png) [@awarunek187](https://forum.inductiveautomation.com/u/awarunek187)\
**Post date:** [December 30, 2020, 9:31pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/8 "2020-12-30T21:31:27Z")

</div>

I saw it in this thread:

> [@Accessing PDF's from a Database Table in Perspective](http://forum.inductiveautomation.com/t/accessing-pdfs-from-a-database-table-in-perspective/25402):
>
> I know with Perspective, the PDF Viewer will only show PDF’s where there’s a web path because of how a web browser works. What I wanted to see is if there’s a way, and if so, what the best practice is to look at PDF’s, images, etc. that are stored in MSSQL database tables. Currently in Vision, we read in the bytes and use the .loadPDFBytes function. I know that doesn’t exist in Perspective, but is there a way to run a script on the Gateway to create the PDF, put it in a location, and then be …

I am able to send pdfs from the report viewer to my DB via a button. I can see the pdfs in the table that I created. I want to be able to display each PDF, in the PDF Viewer or Inline Frame, by just clicking on the row in the table. (This will act as a way to view past entries).

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [December 30, 2020, 9:56pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/9 "2020-12-30T21:56:56Z")

</div>

Ah, okay, yes - that would be a better way I guess, but you’re not supplying each file - you’re supplying a python process which accepts some parameters and then retrieves the report from the database based on the arguments supplied.

The way I suggested requires you to save or place each report into a WebDev mounted folder, but if you do this then you’re sort of doubling up the report because it’s now in your DB and on the file system.

The python route leaves just one copy in the DB and uses python to retrieve each report as needed. I’m not very familiar with the python endpoint route, so I can’t provide any insight into how you’d do that.

---

<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:** [December 30, 2020, 10:09pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/10 "2020-12-30T22:09:02Z")

</div>

> [@cmallonee](#):
>
> python endpoint route

Highly recommended. A search here for "webdev doget" has this near the top:

> [@Report Viewer in Perspective](http://forum.inductiveautomation.com/t/report-viewer-in-perspective/26695):
>
> Hi all, I am currently in the process of upgrading a project made in Ignition 7.9 from Vision to Perspective. On one of the windows for the 7.9 Vision Application, a report viewer component is used to display items created in the reporting module. I noticed there was no report viewer component in the Perspective components palette. Is it still possible to use the reporting module within a perspective window? If so, how would I go about it? Thanks

---

<div class="post-metadata">

**Author:** ![Carl.Gould](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/carl.gould/32/7262_2.png) [@Carl.Gould](https://forum.inductiveautomation.com/u/Carl.Gould)\
**Post date:** [February 12, 2021, 7:09pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/11 "2021-02-12T19:09:35Z")

</div>

Wait, is all you really want here a custom filename for the report download? Like this idea: [https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/perspective-report-viewer-suggested-file-name](https://ideas.inductiveautomation.com/ignition-features-and-ideas/p/perspective-report-viewer-suggested-file-name)

---

<div class="post-metadata">

**Author:** ![Eagel007](https://avatars.discourse-cdn.com/v4/letter/e/7bcc69/32.png) [@Eagel007](https://forum.inductiveautomation.com/u/Eagel007)\
**Post date:** [November 22, 2023, 9:37pm UTC](https://forum.inductiveautomation.com/t/script-on-download-button-on-report-viewer-in-perspective/41862/12 "2023-11-22T21:37:13Z")

</div>

what if file is on IIS server and starts with http?
