send excel file to client using java servlets

2019-02-25 23:24发布

I am using Apache POI for generating Excel file in Java Servlets.

getExcel() function returns HSSFWorkbook, which I want to send to the client.

HSSFWorkbook wb = getExcel();

This is what I have tried so far.

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

//block2
request.setAttribute("Message", str1);
request.setAttribute("MessageDetails", str2);
request.getRequestDispatcher("/MyFile.jsp").forward(request, response);

Above code sends excel file to the client, but gives me exception:

java.lang.IllegalStateException: Cannot forward after response has been committed

If I remove the block1 or block2 from above code then it will not give error, but I want to send client Excel file and two attributes which I have added to request object.

So can send Excel file to client using request.getRequestDispatcher ? Or is there any better way for doing this?

Any suggestion will be appreciated.

Edit1
I know why I am getting the IllegalStateException, but then my question is how should I send ExcelFile and Request Attributes both to the client?

Edit2
The Reason why I want to send both Excel file and Attributes to the client is that MyFile.jsp has a <div> which will show message send from servlet.

<div style="background-color: aliceblue">
    <h3>${Message}</h3>
</div>

Edit3
The Reason why I want to send message to client is that I am sending this Excel file as an response to Import Excel operation in which client will provide excel file for inserting data in database, and then I am highlighting the excel rows which cannot be inserted due to duplication or any other reasons. So I want to show Import statistics in the Message to client and give him copy of excel file with error rows highlighted.

1条回答
走好不送
2楼-- · 2019-02-25 23:58

You are flushing your response and then trying to forward. Container has already sent the response back to the client and now is in a dilemma as to how to forward the request to another JSP, hence it aborts the operation mid way throwing an Exception. HTTP is a request-response model . Once you request , you get back a response . But once the response is already committed the whole transaction is over.

outStream.write(outArray); 
// you already committed the response here by flushing the output stream
outStream.flush(); 

//block2
request.setAttribute("Message", str1);
request.setAttribute("MessageDetails", str2);
// this is illegal after you have already flushed the response
request.getRequestDispatcher("/MyFile.jsp").forward(request, response);

As per the Javadoc:

IllegalStateException - if the response was already committed.

After EDIT1:

No you cannot do both . You need to decide what you want. Write the bytes to the response setting proper HEADERS and MIME-TYPE. You cannot get the browser download something as well as show a JSP page from the same response.

查看更多
登录 后发表回答