pui.download
-
- Profound User
- Posts: 21
- Joined: Mon Dec 15, 2014 5:21 pm
- First Name: Randy
- Last Name: Heinz
- Company Name: Southwestern Motor Transport
- Phone: 210.662.3272
- Address 1: 4600 Goldfield
- City: San Antonio
- State / Province: Texas
- Zip / Postal Code: 78218
- Country: United States
- Contact:
pui.download
I have successfully gotten this pui.download to run within my display file. This is all happening when the event, onclick, is executing. Within java code how do I call an AS400 program to generate the pdf document first and place it on the IFS before it execute the pui.download statement?
-
- Experienced User
- Posts: 2711
- Joined: Wed Aug 01, 2012 8:58 am
- First Name: Scott
- Last Name: Klement
- Company Name: Profound Logic
- City: Milwaukee
- State / Province: Wisconsin
Re: pui.download
Did you mean JavaScript code? Or, are you using Java for something? (We don't use Java in Profound UI, except for executing remote commands.)
The normal process is to code something into the PUIDNLEXIT program. Whatever you provide as an "id" to pui.download() is passed to the exit program, so it can use that information to generate the PDF and download it, it can also delete a temporary object from disk when the download is complete (if that is desired).
For example, let's say you wanted to generate an "item report" PDF file when the user clicks a button. You'd add the button to your screen as normal, but instead of using a "response", you'd code the "onclick" event to something like this:
Calling pui.download( ) will trigger the PUIDNLEXIT program, and it will pass the information (the "id", "inline" and "content type") to the exit program. The program can look something like this:
So here I'm checking for an 'id' (called "fileid" in the RPG program) containing the "itemrpt" string I gave to pui.download(). When that occurs, I know the user wants to run the item report. (the "id" doesn't necessarily have to be the filename, I can set the filenmae in the exit program to whatever I want.)
The 'tmpnam' call you see there is an IBM-supplied API that will generate a unique temporary file name that I can use. That way, I don't have to worry about another user running this report at the same time and having the name clash -- the output of tmpnam() will always be unique. I'm also using %subst() on the output of tmpnam() because it will start with "/tmp/", but the directory should go in a separate "stmfDir" parameter in this exit program, so I'm stripping off the "/tmp/" with %subst.
The "stmfDir" and "stmfName" will be the name of the file that PUI will read from the IFS to send to the browser.
The "attName" parameter is what the user will see as a filename when saving the download. I use "itemReport.pdf" for attName because it's a friendly-sounding name for an item report. (Whereas the output of tmpnam would be something like QAXJ123435 which would not be so friendly.)
This is all only done when the timingFlag=0 because the exit program is called twice. First time timingFlag=0, which means "before the download". timingFlag=1 would mean "after the download".
The "RunItemRpt" routine is something that I wrote to generate the item report -- you can write your own routine to generate a PDF in place of RunItemRpt... you can do whatever you want there, this RunItemRpt is only a simple example to give you the idea... I'm using IBM's 57xx-TS1, the free PDF tools that came out with V6R1 to make a PDF from a "regular" RPG report like this:
Again, don't feel like you have to use the name "RunItemRpt" or code it the way I did... any way you can generate a PDF should be fine, here.. this is just an example. But, it makes a PDF and puts the output into the "tempfile" (which is the filename I made with tmpnam() before).
So this is downloaded to the browser when the PUIDNLEXIT program ends. But, then PUIDNLEXIT is called a second time with timingFlag=1. So I put the following code in the mainline (I have it right after the timingFlag=0 code in the mainline...)
This code uses the unlink() API (an IBM-supplied API) to delete the temporary file (the one from tmpnam() that we created in the RunItemRpt() routine) from the IFS. This way, the temporary files are always cleaned up after the user downloads them.
So that's how I go about handling PDF downloads, I just have the exit program generate the PDF file on the fly. Mind you, there's no reason why you couldn't do a separate call to generate the PDF -- that'd work, too... but this way seems simpler and easier to understand to me.
All of that assumes, of course, that I understand your scenario. The bit about "Java" makes me wonder if I'm not understanding... but, probably you meant JavaScript.
The normal process is to code something into the PUIDNLEXIT program. Whatever you provide as an "id" to pui.download() is passed to the exit program, so it can use that information to generate the PDF and download it, it can also delete a temporary object from disk when the download is complete (if that is desired).
For example, let's say you wanted to generate an "item report" PDF file when the user clicks a button. You'd add the button to your screen as normal, but instead of using a "response", you'd code the "onclick" event to something like this:
Code: Select all
pui.download({ "id": "itemrpt", "inline": true, "contentType": "application/pdf" });
Code: Select all
**********************************************************************************************
* *
* Description: Profound UI File Download Exit Program *
* *
* Compile as PUIDNLEXIT in PROFOUNDUI product library using CRTBNDRPG. *
* *
* Return 1 in 'Allow' parameter to allow the upload, any other value will *
* prevent the upload. *
* *
**********************************************************************************************
H DFTACTGRP(*NO) ACTGRP(*CALLER)
D InputData_t ds qualified
D based(Template)
D fileid 640a varying
D userid 10a
D ipAddr 15a
D inline 1n
D Main PR ExtPgm('PUIDNLEXIT')
D timingFlag 10i 0 const
D inputData likeds(InputData_t) const
D stmfDir 640a varying
D stmfName 256a varying
D attName 256a varying
D contentType 255a varying
D allow 5i 0
D Main PI
D timingFlag 10i 0 const
D inputData likeds(InputData_t) const
D stmfDir 640a varying
D stmfName 256a varying
D attName 256a varying
D contentType 255a varying
D allow 5i 0
D RunItemRpt PR
D tempfile 50a varying const
D tmpnam PR * extproc('_C_IFS_tmpnam')
D string 39A options(*omit)
D unlink PR 10I 0 ExtProc('unlink')
D path * Value options(*string)
D CmdExc PR ExtPgm('QCMDEXC')
D cmd 32702a const options(*varsize)
D len 15p 5 const
/free
allow = 0;
if timingFlag=0;
select;
when inputData.fileId = 'itemrpt';
stmfDir = '/tmp';
stmfName = %subst(%str(tmpnam(*omit)):6) + '.pdf';
attName = 'itemReport.pdf';
contentType = 'application/pdf';
RunItemRpt( stmfDir + '/' + stmfName );
allow = 1;
when itemData.fileId = 'SOMETHING ELSE';
// you can handle other reports/downloads here, etc...
endsl;
endif;
The 'tmpnam' call you see there is an IBM-supplied API that will generate a unique temporary file name that I can use. That way, I don't have to worry about another user running this report at the same time and having the name clash -- the output of tmpnam() will always be unique. I'm also using %subst() on the output of tmpnam() because it will start with "/tmp/", but the directory should go in a separate "stmfDir" parameter in this exit program, so I'm stripping off the "/tmp/" with %subst.
The "stmfDir" and "stmfName" will be the name of the file that PUI will read from the IFS to send to the browser.
The "attName" parameter is what the user will see as a filename when saving the download. I use "itemReport.pdf" for attName because it's a friendly-sounding name for an item report. (Whereas the output of tmpnam would be something like QAXJ123435 which would not be so friendly.)
This is all only done when the timingFlag=0 because the exit program is called twice. First time timingFlag=0, which means "before the download". timingFlag=1 would mean "after the download".
The "RunItemRpt" routine is something that I wrote to generate the item report -- you can write your own routine to generate a PDF in place of RunItemRpt... you can do whatever you want there, this RunItemRpt is only a simple example to give you the idea... I'm using IBM's 57xx-TS1, the free PDF tools that came out with V6R1 to make a PDF from a "regular" RPG report like this:
Code: Select all
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* RunItemRpt(): Run the RPG program that generates
* an item report
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P RunItemRpt B
D PI
D tempfile 50a varying const
D ITM001R PR ExtPgm('ITM001R')
D cmd s 500a varying
/free
// Run the Item Report and override the output to
// a PDF file in the temporary name
cmd = 'OVRPRTF FILE(QSYSPRT) DEVTYPE(*AFPDS) WSCST(*PDF) +
OVRSCOPE(*CALLLVL) +
TOSTMF(''' + TempFile + ''')';
CmdExc(cmd: %len(cmd));
ITM001R();
cmd = 'DLTOVR FILE(QSYSPRT) LVL(*)';
CmdExc(cmd: %len(cmd));
/end-free
P E
So this is downloaded to the browser when the PUIDNLEXIT program ends. But, then PUIDNLEXIT is called a second time with timingFlag=1. So I put the following code in the mainline (I have it right after the timingFlag=0 code in the mainline...)
Code: Select all
if timingFlag=1 and inputData.fileId='itemrpt';
unlink( stmfDir + '/' + stmfName );
endif;
*inlr = *on;
/end-free
So that's how I go about handling PDF downloads, I just have the exit program generate the PDF file on the fly. Mind you, there's no reason why you couldn't do a separate call to generate the PDF -- that'd work, too... but this way seems simpler and easier to understand to me.
All of that assumes, of course, that I understand your scenario. The bit about "Java" makes me wonder if I'm not understanding... but, probably you meant JavaScript.
Who is online
Users browsing this forum: Ahrefs [Bot] and 11 guests