Link to home
Start Free TrialLog in
Avatar of dirku
dirkuFlag for Germany

asked on

Display a PDF or Excel file in a JSP

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?
Avatar of enachemc
enachemc
Flag of Afghanistan image

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.
Avatar of dirku

ASKER

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.
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);
ASKER CERTIFIED SOLUTION
Avatar of dasmaer
dasmaer
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of dirku

ASKER

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