Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an excel file for users to download using Apache POI

I'm able to create an excel file using apache poi. however, i want users to be able to download this as a "true" excel file. the effect i want to achieve would be to have a popup box allowing the user to download the file. this is similar to using

<%@ page contentType="application/vnd.ms-excel" pageEncoding="ISO-8859-1"%> 
<%response.setHeader("Content-Disposition", "attachment;filename=myfile.xls"); %>

with one critical exception: i must allow the user to download a proper excel file. i read somewhere the above code simply says to the client that the server is sending an excel file

like image 312
user571099 Avatar asked Jun 27 '12 12:06

user571099


2 Answers

Do the job in a normal servlet instead of a JSP file. A JSP file is meant for dynamically generating HTML code and is using a character writer for that instead of a binary output stream and would thus only corrupt your POI-generated Excel file which is in essence a binary stream.

So, basically all you need to do in the doGet() method of the servlet is the following:

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=filename.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
// ...
// Now populate workbook the usual way.
// ...
workbook.write(response.getOutputStream()); // Write workbook to response.
workbook.close();

Now, to download it, invoke the servlet by its URL instead of the JSP file.

like image 159
BalusC Avatar answered Oct 02 '22 13:10

BalusC


While it is true that it is more usual to write a binary attachment using a servlet rather than a jsp, it is certainly possible to write a binary attachment from a jsp. And the advantage of doing so is that you need not worry about configuring web.xml or reloading your application. That can be an important consideration, depending on your web server environment.

Here is an example jsp that uses poi to send a binary attachment to a browser.

<%@page import="org.apache.poi.hssf.usermodel.*" %><%@page import="java.io.*" %><%

// create a small spreadsheet
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell(0);
cell.setCellValue("Some text");

// write it as an excel attachment
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
wb.write(outByteStream);
byte [] outArray = outByteStream.toByteArray();
response.setContentType("application/ms-excel");
response.setContentLength(outArray.length);
response.setHeader("Expires:", "0"); // eliminates browser caching
response.setHeader("Content-Disposition", "attachment; filename=testxls.xls");
OutputStream outStream = response.getOutputStream();
outStream.write(outArray);
outStream.flush();

%>

The important trick is to make sure there is only one line with all your imports and other directives prior to the "<%" that begins your code. Otherwise, the jsp may output some initial new lines and corrupt your output.

Also, I suggest you always set the content length. Some browsers will not work correctly if it is not set. That is why I first output my spreadsheet to a byte array, so I could set the length prior to actually sending the data.

like image 28
Howard Schutzman Avatar answered Sep 29 '22 13:09

Howard Schutzman