I have a web page which links to an Excel 2007 worksheet. It is a upload details in .xlsx file and download in .csv file. When I click on the download link and trying to open i get the usual dialog box to either open/save the Excel file. On clicking 'Open', I get the following warning message-
The file you are trying to open, 'filename.csv' is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?
I developed this code in Java
private void downloadExcelSheet(HSSFWorkbook workbook, String sheetName){
OutputStream out = null;
try{
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
workbook.write(outByteStream);
byte[] bytes = outByteStream.toByteArray(); //workbook.getBytes()
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.reset();
String disHeader = "Attachment;Filename=\""+sheetName+".csv\"";
response.addHeader("Content-Disposition", disHeader);
response.setContentType("text/csv");
//response.setHeader("Content-Disposition", "attachment; filename=\""+sheetName+".csv");
//response.setContentType("text/csv");
response.setContentLength(bytes.length);
out = response.getOutputStream();
out.write(bytes);
out.flush();
}catch(IOException ioe){
ioe.printStackTrace();
}
catch(Exception e){
e.printStackTrace();
}
finally{
try{
if(out!=null){
out.close();
}
}catch(IOException io){
io.printStackTrace();
}
}
}
Related
I am working on a Java1.7 Struts1 application.
It can successfully download a file by doing the following:
response.setContentType("text/html");
response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
BufferedOutputStream fos = null;
try {
OutputStream output = response.getOutputStream();
fos = new BufferedOutputStream(output);
fos.write(bytes);
fos.flush();
fos.close();
} catch (IOException e) {
logger.error("Error trying to download the BAS file. "+e.getMessage());
}
However, when when it does this, it changes the HttpServletResponse object. This means that when the Action class performs the following:
return mapping.findForward(forwards.success.toString());
It does not forward to that location (it just stays on the current page, i.e. does the download and nothing else).
If it does not do the download, i.e. does not change the HttpServletResponse object, then it does the forward successfully.
Question
How can I make it download the file (i.e. write to the HttpServletResponse, and then do the forward succesfully?
So here is the situation:
I have a .xslm file (a macro enabled excel worksheet) on server. There are no issues in opening this file on server (using ms-excel 2013).
I then edit the file using Apache POI 3.13. Save a copy of this file on server and give the other to the user for download.
(This is done just to check if we have any write issues while editing. The original purpose was just to give it as download)
The copy of this file saved on server is opened without any issues. But the one sent as download throws this error while opening it from excel 2013.
I am using Jquery.fileDownload() on the client side to make the ajax call to the server where I have my Spring Controller serving the file.
Here is my code to write the file:
Workbook workbook = null;
ServletOutputStream out = null;
InputStream inputStream = null;
FileOutputStream fos = null;
try {
OPCPackage inputFilePackage = OPCPackage.open(<original file saved on server>);
workbook = WorkbookFactory.create(inputFilePackage);
//Do Some stuff to edit workbook here
fos = new FileOutputStream("temp.xlsm");
workbook.write(fos);
fos.close();
inputStream = new FileInputStream("temp.xlsm"); // The file that is created just now
servletResponse.setContentType("application/vnd.ms-excel.sheet.macroEnabled.12");
servletResponse.setHeader("content-disposition", "attachment; filename=NewFile.xlsm");
servletResponse.setHeader("Set-Cookie", "fileDownload=true; path=/");
out = servletResponse.getOutputStream();
// workbook.write(out); // Was previously using this method to directly write to ServletOutputStream
int i;
while ((i = inputStream.read()) != -1) {
out.write(i);
}
out.flush();
// new File("temp.xlsm").delete();
}
catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
finally {
if (out != null) {
try {
out.close();
}
catch (Exception ex) {
LOGGER.error(ex.getMessage());
}
}
if (inputStream != null) {
try {
inputStream.close();
}
catch (Exception ex) {
LOGGER.error(ex.getMessage());
}
}
}
return "success";
Also I can clearly see the difference between the size of both the files.
The file which is opening without issues is (436,129 bytes) while the file throwing the error is (436,136 bytes). I am not sure from where these extra bytes are coming.
Any help would be greatly appreciated.
I want to create an Excel file from a method in Java and download it in a browser.
I have found an example on this post where you create the Excel file, but I want to create the .xls file and download it from a web browser.
How can I do that?
I finally found a solution for my problem...!!
This is working for me:
#RequestMapping("/downloadFile")
public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
try {
String fileName = "C:/excelFile.xls";
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("firstSheet");
HSSFRow rowhead = sheet.createRow((short) 0);
rowhead.createCell(0).setCellValue("No.");
rowhead.createCell(1).setCellValue("Name");
rowhead.createCell(2).setCellValue("Address");
rowhead.createCell(3).setCellValue("Email");
HSSFRow row = sheet.createRow((short) 1);
row.createCell(0).setCellValue("1");
row.createCell(1).setCellValue("Carlos");
row.createCell(2).setCellValue("Costa Rica");
row.createCell(3).setCellValue("myNameh#gmail.com");
FileOutputStream fileOut = new FileOutputStream(fileName);
workbook.write(fileOut);
fileOut.close();
System.out.println("Your excel file has been generated!");
//Code to download
File fileToDownload = new File(fileName);
InputStream in = new FileInputStream(fileToDownload);
// Gets MIME type of the file
String mimeType = new MimetypesFileTypeMap().getContentType(fileName);
if (mimeType == null) {
// Set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
System.out.println("MIME type: " + mimeType);
// Modifies response
response.setContentType(mimeType);
response.setContentLength((int) fileToDownload.length());
// Forces download
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", fileToDownload.getName());
response.setHeader(headerKey, headerValue);
// obtains response's output stream
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
in.close();
outStream.close();
System.out.println("File downloaded at client successfully");
} catch (Exception ex) {
System.out.println(ex);
}
}
If you want to trigger a Java process from a Web Browser (HTTP request), then you need an application server (like Tomcat) to accept your HTTP request and execute some server-side code (Servlet). A main method like in the example cannot be launched by a HTTP request. Look here if you never wrote a Servlet before.
This has nothing to do with Excel, but this post shows how to download a file from a Spring MVC controler.
#RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
public void getFile(#PathVariable("file_name") String fileName, HttpServletResponse response) {
try {
// get your file as InputStream
InputStream is = ...;
// copy it to response's OutputStream
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
} catch (IOException ex) {
log.info("Error writing file to output stream. Filename was '{}'", fileName, ex);
throw new RuntimeException("IOError writing file to output stream");
}
}
I am trying to add a function to my web app which lets the users download an excel file.
I'm trying to achieve this with the following code:
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
File file = new File("d:/test/test.xls");
response.setContentType("application/xls");
response.addHeader("Content-Disposition", "attachment; filename=test.xls");
response.setContentLength((int) file.length());
try {
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream responseOutputStream = response.getOutputStream();
int bytes;
while ((bytes = fileInputStream.read()) != -1) {
responseOutputStream.write(bytes);
}
fileInputStream.close();
responseOutputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I'm able to download the excel file with the above code, however the file is corrupted. If I open it with microsoft excel, I get a popup with the message:
"the file format and extension of don't match. the file could be corrupted or unsafe".
And the excel file is empty.
After running the code, the original file(d:/test/test.xls) gets also corrupted.
What am I doing wrong?
The official MIME type for Excel file .xls is application/vnd.ms-excel and for .xlsx is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.
Also, I would suggest doing response.reset() prior to writing to the output stream and responseOutputStream.flush() (important) prior to closing the response.
Try below code :
File file = null;
InputStream in = null;
OutputStream outstream = null;
try {
response.reset();
in = new FileInputStream(file);
response.setContentType("application/vnd.ms-excel");
response.addHeader("content-disposition", "attachment; filename=data.xls");
outstream = response.getOutputStream();
IOUtils.copyLarge(in, outstream);
}
catch (Exception e) {
out.write("Unable to download file");
}finally {
IOUtils.closeQuietly(outstream);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
if (file != null)
file.delete();
}
dont forgot to add apache commons-io-2.4 in your dependency
I have written a program to upload and download files (.doc, .xls and .txt) from DB (mySQL). It is written using Spring MVC. The upload and download is working correctly in IE however in Firefox it is not working as excepted.
To download the file a link is provided in the JSP on click of which the "File Download" dialog box will pop-up. In IE this dialog box pops up and allows to open and/or save the file in the correct format (i.e. .doc, .xls and/or .txt).
In Firefox it is doing the following on click on the link :
For .doc files, it opens the files (no File Download pop-up)
For .xls files, the File Download pop-up is seen however the file extension is not taken as .xls instead taking it as file.do
FileController Class
public class FileController extends AbstractFormController{
SearchResultService searchResultService;
public void setSearchResultService(SearchResultService searchResultService){
this.searchResultService = searchResultService;
}
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
ResultSet result = searchResultService.getAttachment(Integer.parseInt(arg0.getParameter("prbId")));
byte[] buff = new byte[100000];
try {
result.next();
if(!(result.getBinaryStream(1)==null)){
String filename = "fname."+result.getString("file_ext");
if(result.getString("file_ext").equals("txt")){
InputStream is = result.getBinaryStream(1);
OutputStream out = arg1.getOutputStream();
arg1.reset();
int bytesRead;
while ((bytesRead = is.read(buff)) != -1) {
out.write(buff, 0, bytesRead);
}
arg1.setContentType("");
arg1.setHeader("content-disposition", "attachment; filename="+filename);
is.close();
out.flush();
out.close();
}else{
arg1.reset();
if(result.getString("file_ext").equals("doc")||result.getString("file_ext").equals("docx")){
arg1.setContentType("application/msword");
}else if(result.getString("file_ext").equals("xls")||result.getString("file_ext").equals("xlsx")){
arg1.setContentType("application/vnd.ms-excel");
}else if(result.getString("file_ext").equals("pdf")){
arg1.setContentType("application/pdf");
}
arg1.setHeader("Content-Desposition","attachment; filename="+filename);
byte[] bytesGot = result.getBytes(1);
ServletOutputStream outs = arg1.getOutputStream();
outs.write(bytesGot);
outs.flush();
outs.close();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return new ModelAndView();
}
}
JSP that calls FileController class
Download File
All the extensions are saved/retrieved in the db correctly. Please help.
For point 2 - You have a spelling mistake in setting the header.
arg1.setHeader("Content-Desposition","attachment; filename="+filename);
It should be Content-Disposition not Content-Desposition.
For point 1 - try resetting your browser preferences. See this link for more information.
You need to set proper headers. I am setting these headers to download my .xls file and its working.
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-download");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setHeader("Content-Transfer-Encoding", "binary");
public class FileController extends AbstractFormController{
SearchResultService searchResultService;
public void setSearchResultService(SearchResultService searchResultService){
this.searchResultService = searchResultService;
}
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
ResultSet result = searchResultService.getAttachment(Integer.parseInt(arg0.getParameter("prbId")));
byte[] buff = new byte[100000];
try {
result.next();
if(!(result.getBinaryStream(1)==null)){
String filename = "fname."+result.getString("file_ext");
if(result.getString("file_ext").equals("txt")){
InputStream is = result.getBinaryStream(1);
OutputStream out = arg1.getOutputStream();
arg1.reset();
int bytesRead;
while ((bytesRead = is.read(buff)) != -1) {
out.write(buff, 0, bytesRead);
}
response.setContentType("text/plain");
arg1.setHeader("content-disposition", "attachment; filename="+filename);
is.close();
out.flush();
out.close();
}else{
arg1.reset();
if(result.getString("file_ext").equals("doc")||result.getString("file_ext").equals("docx")){
arg1.setContentType("application/msword");
}else if(result.getString("file_ext").equals("xls")||result.getString("file_ext").equals("xlsx")){
arg1.setContentType("application/msexcel");
}else if(result.getString("file_ext").equals("pdf")){
arg1.setContentType("application/pdf");
}
arg1.setHeader("Content-Disposition","attachment; filename="+filename);
byte[] bytesGot = result.getBytes(1);
ServletOutputStream outs = arg1.getOutputStream();
outs.write(bytesGot);
outs.flush();
outs.close();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return new ModelAndView();
}
}