Question

How to download file from server using anchor links?

Hi,

We are using pega 6.1 SP2. We have a requirement to show the list of files in the server location as links to download but server location is a folder parallel to PegaTempDir folder but not within the pegaTempDir. How to access the path?

**Moderation Team has archived post**

This post has been archived for educational purposes. Contents and links will no longer be updated. If you have the same/similar question, please write a new post.

Correct Answer
November 7, 2016 - 11:49pm

With the above approach, we got out of memory issues if the file size is more than 200MB. So did the below approach and it is fine

1. In java script function, call ajax asynchronously to copy the data into service export path

2. From URL of service export and call to open the url

3. Later step 2 call ajax to remove the file from service export

Comments

Keep up to date on this post and subscribe to comments

Pega
October 6, 2016 - 4:53am

Here's one way of doing it:

Basically: you need to reference the System Page 'pxThread' to get hold of the '.pxReqExportURI' property and append to your filename (with relevant separators  - and any subdirectories you may have).

I got this answer by running a TRACER from within Designer Studio :

Pega Button > Application > Import & Export > Export

Then chose criteria which resulted in a small export set (so it didn't take ages); I used

Ruleset: Pega-WB

RuleSet Version: 06-01-25

I made sure I switched on the 'Stream Rules' option within Tracer and Traced the export; this showed the following Stream Rule was used to display the link: (with a bit of guesswork on my part here):

@baseclass.PegaRULESMove_Progress|Pega-ImportExport:06-01-20

Within that Stream Rule; you can search for the text that is displayed in the Export Process:

"Zip file created. Click here to save"

And that showed the following mixture of HTML, JSP and Javascript that generates the link:

  1. // Provide a download link to save the file locally.
  2. var strFilePath = '<pega:reference name="pxThread.pxReqExportURI" mode="normal" />' +
  3. '<%= PRFile.separator %>' + strFileName;
  4. lblMessage.innerHTML = "<html><a class=ProgLabel href=\"" + strFilePath + "\">" +
  5. "<U><B>Zip file created. Click here to save " + strFileName +
  6. " file locally</B></U></a></html>";
  7. [...]

So I took this and created a test Activity of my own which does this:

Property-Set .downloadURL = pxThread.pxReqExportURI + @java( "PRFile.separator" ) + Param.filename

Where ".downloadURL" is just a simple Text Property in my Class Structure (could have also done it with PARAMs probably).

And then I created a HTML rule which does this:

  1. <html>
  2. <head>
  3. <title> Download File </title>
  4. </head>
  5. <body>
  6. <a href="<p:r n='MyPage.downloadURL' m='literal'/>"> Click To Download File </a>
  7. </body>
  8. </html>

Here's some screenshots of my Activity and Stream Rule:

And the Stream Rule that gets called by the Activity:

 

And running it ('hello.txt' has to exist on the Server 'ServiceExport' directory of course!):

 

Cheers

John

 

 

 

 

 

Pega
October 6, 2016 - 5:09am

oops: I just noticed you needed to load a file from outside 'PegaTemp' (which includes 'StaticContent').

You probably want to use 'PRFile' and/or standard Java 'File' methods to move that file into the 'StaticContent' directory - not great security to have your App referencing arbitary directories with a URL pointing at them though.....

October 6, 2016 - 8:01am

I need to display all files of the folder with anchored links and on click, file should be downloaded. To create link, need to determine absolute URL path which i could not understand how to get it.

Pega
October 6, 2016 - 8:43am

So - does PRPC even need to see these files (are you just providing a mechanism to download files from a web server?) You could build your own Servlet that does this and include a reference to this custom Servlet from your PRPC's 'web.xml'.

In the case above: this really has nothing to do with PRPC: you would just be using the App Server that PRPC is deployed to provide a 'static' web site really ?

Alternatively: to avoid having to customize PRPC's 'web.xml' (which probably isn't a good idea unless you really have to); you could deploy a complete separate Web App ; which you can link to from PRPC (no problem: links are followed by the Browser; not the Server); if you are using Tomcat; there is a built-in Servlet to allow this sort of thing  ("Default Servlet") : see https://tomcat.apache.org/tomcat-6.0-doc/default-servlet.html for instance.

One thing about using a separate Web App: this will not be authenticated by the Logged-in PRPC Operator - you may need to take that into account also.

If you do need PRPC to 'see' these files; then perhaps code the Java (using standard Java APIs : see this for instance : http://stackoverflow.com/questions/5694385/getting-the-filenames-of-all-files-in-a-folder ), and then use a 'pyActivity' URL to call the Activity which would stream the result when clicked.

Or else: consider using a File Listener to process the files and store them within PRPC; then use standard mechanism (JSP 'pega tags' etc) to allow the downloading/streaming of the copies of the files.

 

 

Pega
October 6, 2016 - 8:45am

Or (if your PRPC system is hosted on Linux or Unix) : consider using 'Symbolic Links' to make the files available within the standard 'ServiceExport' directory ? (Note: I haven't tried this, so it may be the Web Server/Servlet won't follow Symbolic Links, but it's worth a shot).

 

 

October 10, 2016 - 4:41am

Thanks John,

As suggested, i I could able to list down all the files from the folder using Java Pega APIs, Now i am looking for how to stream the data for multiple CSV files with varied columns in each file?

I have gone through ExportExcel functionality which forms the HTML page with columns and rows as table and send it to browser. How to do it for multiple CSV files?

 

Also, i found the below java code

public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String filename = "home.jsp"; 
String filepath = "e:\\"; 
response.setContentType("APPLICATION/OCTET-STREAM"); 
response.setHeader("Content-Disposition","attachment; filename=\"" + filename + "\""); 
FileInputStream fileInputStream = new FileInputStream(filepath + filename);
int i; 
while ((i=fileInputStream.read()) != -1) {
out.write(i); 

fileInputStream.close(); 
out.close(); 

What is the out object (or how to set outstream data) that i can use in pega to send the data to browser?

 

October 10, 2016 - 4:43am

Screenshot of Rule-Obj-HTML.ViewExcelData activity added. if you cannot see the screenshot, please see this activity.

October 21, 2016 - 8:06am

I could able to acheive using java

On click on link, call javascript function which calls an activity in new window

Step1:

New activity has a step Property-Set-HTML which copies the content of a file to out object. (Create fileinputstream object with the full context path and writes data to out object.)

<%

FileInputStream fileInputStream = new FileInputStream(filepath + filename);
int i; 
while ((i=fileInputStream.read()) != -1) {
out.write(i); 

fileInputStream.close(); 

%>

Step 2: Next set Obj headers such as contentType, ContentDisposition and file names in another java method (Refer Rule-Obj-HTML.ViewExcelData activity).

Step3: Next Show-property of data set in step 1.

Options are available to Open/Save file.

 

November 7, 2016 - 11:49pm

With the above approach, we got out of memory issues if the file size is more than 200MB. So did the below approach and it is fine

1. In java script function, call ajax asynchronously to copy the data into service export path

2. From URL of service export and call to open the url

3. Later step 2 call ajax to remove the file from service export

December 13, 2016 - 7:54pm
Response to NaveenM4289

Can you share the Javascript function and Ajax function details for this purpose?