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?

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?

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.

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.

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) where you construct the filepath argument from ReportViewer.props.source. Something like this:

filename = self.getSibling('ReportViewer').props.source
filepath = "C:\\path\to\file\" + filename

# Use a query to insert the file
query = "INSERT INTO files (filename, filedata) VALUES(?, ?)"
args = [filename, filedata]
system.db.runPrepUpdate(query, args)


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.

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.

I saw it in this thread:

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).

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.

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

1 Like

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