When i create and download file using AbstractExcelView in spring application, it will download as .html file.But when i change its extension as .xls manually ,it shows expected result. My code for AbstractExcelView is :
public class ExcelRevenueReportView extends AbstractExcelView {
@Override
protected void buildExcelDocument(Map model, HSSFWorkbook workbook,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
Map<String, String> revenueData = (Map<String, String>) model
.get("revenueData");
// create a wordsheet
HSSFSheet sheet = workbook.createSheet("Revenue Report");
HSSFRow header = sheet.createRow(0);
header.createCell(0).setCellValue("Month");
header.createCell(1).setCellValue("Revenue");
int rowNum = 1;
for (Map.Entry<String, String> entry : revenueData.entrySet()) {
// create the row data
HSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(entry.getKey());
row.createCell(1).setCellValue(entry.getValue());
}
}
}
The context configuration file :dispatcher-servlet.xml is
<beans:bean name="/index.html" class="com.my.report.HomeController">
</beans:bean>
<beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
<beans:property name="location" value="/WEB-INF/spring-excel-views.xml" />
<beans:property name="order" value="0" />
</beans:bean>
When it comes to HTTP and Web Applications (spring or not), there are many options.
Some ideas:
1 - Forcing the "Save-As" Dialog to show up, giving the users the ability to save the file as they want (possibly renaming them and their extensions).
This can be accomplished by setting the HTTP "content-type" header to "application/octet-stream". This literally tells the browser that the data is a byte-stream of unknown kind. That makes the browser "understand" that it is to be opened/handled by another application. Therefore the browser proceeds by allowing you to save the file.
You only provided the buildExcelDocument view manager code. While one can't really say what code is executed previously or after this method, one way of setting this HTTP header is simply using the "HttpServletResponse" object:
response.setHeader("Content-Type", "application/octet-stream");
One other (uglier) way is to hard-code it into the XML/HTML view:
<meta http-equiv="Content-Type" content="application/octet-stream />
This could work nice if your system had a page whose sole purpose were to download the file. If you build your view out of chunks and if you have only one master http page, forcing the meta-tag would mess with other views.
2 - You can also set the extension by forcing a given filename.
You can accomplish it the same way as the first suggestion: by setting a specific content-disposition HTTP header:
// Set file name and extension
response.setHeader("Content-Disposition", "inline; filename=yourExcelFile.xls");
This will set the stream to correctly be downloaded as the filename and extension you state.
Again, this can be placed directly in the HTML/XML/JSP/JSF (or whatever technology) itself, but this isn't the best solution.
I'd go with the "setHeader" way and I'd use both ideas simultaneously:
// Force save-as dialog:
response.setHeader("Content-Type", "application/octet-stream");
// Set file name and extension
response.setHeader("Content-Disposition", "inline; filename=yourExcelFile.xls");
Try this:
response.setHeader("Content-Disposition", "attachment; filename=\"yourFile.xls\"");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With