?
Solved

Display a PDF or Excel file in a JSP

Posted on 2006-11-28
5
Medium Priority
?
4,119 Views
Last Modified: 2012-06-21
I have a JSP displaying a table. The last columns of each row shows a button (better a link?) which causes generating either a PDF or a MS Excel file.

I want to display the generated file in a new browser window so that the user can choose to print or to save the file. How can I achieve this?
0
Comment
Question by:dirku
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 12

Expert Comment

by:enachemc
ID: 18029230
you can only do that in Internet Explorer. This is a nonstandard feature of IE. Just provide the apropiate content-type header to the document when sending it to the client, and IE will take care of it. You will need a servlet to do this.
0
 

Author Comment

by:dirku
ID: 18029338
Well, it's ok that the browser asks the user if he wants to open the file with a particular application (eg. MS Excel) or if he wants to save the file.

I am already generating the file using a servlet. The resulting file is located somewhere in the file system. What is the Java code in the servlet to send the file back to the user/browser?

In the JSP there is the button to submit the request to the server.
The servlet is creating the PDF/Excel file and stores it in the server's file system.
--> What's next? How can I get the result back to the user? The requested file (PDF/Excel) shall not be displayed in the browser window which shows the JSP with the list/table. I want to 'stay there' and open another browser asjing the user to open/save the report.
0
 
LVL 12

Expert Comment

by:enachemc
ID: 18029556
you have two options for serving the file back to the user:
1. place the file in a directory within your server and let the user access the file as any other file on your web server
2. if you, from any reason, do not want to do that, will have to make the servlet feed the content of the file to the user. Just open an input stream for the file and feed it to the output stream of the servlet (not the print writer); send along the required headers (content type, attachement name, size - make sure you send the headers prior to sending evena byte from the file, or you'll receive errors);
0
 
LVL 5

Accepted Solution

by:
dasmaer earned 300 total points
ID: 18031659
If you get your servlet to send the following HTTP headers to the browser (for pdf):

Content-type: application/pdf
Content-Disposition: attachment; filename="downloaded.pdf"

This will force the browser to display a save file dialog. When you want the file to be shown inline, change to:

Content-type: application/pdf
Content-Disposition: inline; filename="downloaded.pdf"

However, this will not always work... Firefox for example will have trouble opening an Excel viewer and will get a file download prompt anyway.

If you want to have the content dynamically streamed to the brower - keep the code above, but write a servlet that will write a byte stream and name it something like "/streamer" (or whatever it is that is creating your spreadsheet/pdf) and have the filename part of the header point to your new servlet.  

For this solution you'd need two JSP's:
   1: the presentation page that will first attempt to send the headers outlined above. If the
       users browser can't handle it, then give them some handy link in the page so they can
       still download it.
   2: the servlet that generates your excel spreadsheet.

What you do is submit to your spreadsheet servlet, and your spreadsheet servlet can then make the spreadsheet, then forward to the presentation page...

hope this solves your problem. post me back if not.
0
 

Author Comment

by:dirku
ID: 18053195
I played around after reading some documentation and now I implemented it this way:
          String fileFormat = request.getParameter("fileFormat");
            
            if ( fileFormat != null )
            {
                  Integer dataId = null;
                  try {
                        dataId = new Integer(RequestUtils.getRequiredIntParameter( request,
                              "dataId" ));
                  } catch (ServletRequestBindingException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                  }
            
                  // hier ggf. schon Format prüfen...
                  String fileUrl = checklistApplicationManager.downloadChecklist(dataId,
                        fileFormat,
                        request.getSession().getServletContext().getRealPath(""));

                  ServletOutputStream out = response.getOutputStream();

                  File file = new File(fileUrl);
                  
                  response.setHeader("Pragma", "public");
                  response.setHeader("Expires", "0");
                  response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
                  //response.setHeader("Content-Type", "application/octet-stream");
                  if ( fileFormat.equalsIgnoreCase("pdf") )
                  {
                        response.setHeader("Content-Type", "application/pdf");
                  } else if ( fileFormat.equalsIgnoreCase("xls") )
                  {
                        response.setHeader("Content-Type", "application/vnd.ms-excel");
                  } else
                  {
                        response.setHeader("Content-Type", "application/octet-stream");
                  }
                  response.setHeader("Content-Transfer-Encoding", "binary");
                  response.setHeader("Content-Length", String.valueOf(file.length()));
                  // Display an open/download prompt to the user.
                  response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
                  // Open the file within the browser using a browser plugin instead
                  // of the standalone application.
                  //response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
                  
                  BufferedInputStream is = new BufferedInputStream(new FileInputStream(file));
                  byte[] buf = new byte[4 * 1024]; // 4K buffer
                  int bytesRead;
                  while ((bytesRead = is.read(buf)) != -1)
                  {
                        out.write(buf, 0, bytesRead);
                  }//end while ((bytesRead = is.read(buf)) != -1)
                  is.close();
                  out.close();
                  
                  checklistApplicationManager.deleteFile(fileUrl);
            }

Well, dasmaer, although implemented independently looks quiet similar to what you've suggested, doesn't it?

I think it would be fair to grant the points to you. (Hehe, I should have post my solution earlier.)

Thanks a lot and best regards form Berlin, Gemrany.

dirku
0

Featured Post

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The top devops trends for 2017 are focused on improved deployment frequency, decreased lead time for change and decreased MTTR.
Ready to get certified? Check out some courses that help you prepare for third-party exams.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question