Spring OutputStream - download pptx with IE - java

I use this Java code to download files from a web application:
#RequestMapping(value = "/filedownloads/filedownload/{userid}/{projectid}/{documentfileid}/{version}/", method = RequestMethod.GET)
public void filesDownload(final #PathVariable("userid") String userId, final #PathVariable("projectid") String projectId,
final #PathVariable("documentfileid") String documentFileId, final #PathVariable("version") String version,
final HttpServletResponse response) throws IOException, BusinessException {
...
final String fileName = "filename=" + documentFile.getFileName();
final InputStream is = new FileInputStream(filePath);
response.setHeader("Content-Disposition", "inline; " + fileName);
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
}
if I will download a pptx- file I get the following IE- page:
What I want to do is to open the downloaded file in Powerpoint.
My question now would be if there is a header setting in order to open this file with the right application (in this case Powerpoint)

Simply try to set the Content Type header properly which is application/vnd.openxmlformats-officedocument.presentationml.presentation in case a pptx, as next:
response.setContentType(
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
);
response.setHeader(
"Content-Disposition",
String.format("inline; filename=\"%s\"", documentFile.getFileName())
);
response.setContentLength((int) new File(filePath).length());
Here is the list of mime types corresponding to Office 2007 documents.

Here is a little sample code from a Spring MVC Controller:
#RequestMapping("/ppt")
public void downloadPpt(HttpServletRequest request, HttpServletResponse response) throws IOException {
Resource resource = new ClassPathResource("Presentation1.pptx");
InputStream resourceInputStream = resource.getInputStream();
response.setHeader("Content-Disposition", "attachment; filename=\"Presentation1.pptx\"");
response.setContentLengthLong(resource.contentLength());
byte[] buffer = new byte[1024];
int len;
while ((len = resourceInputStream.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, len);
}
}
By setting the Content-Disposition to attachment, you're telling the browser to download this file as an attachment and by supplying the correct file name with extension, you're telling the Operating System to use whatever application the user normally uses to open a file of this type. In this case it will be MS Power Point.
This way you can get away with not knowing exactly what version of Power Point the file was created with.

I have tested code in IE-11 its work fine. See below code i.e
#RequestMapping(value = "/downloadfile", method = RequestMethod.GET)
#ResponseBody
public void downloadfile(HttpServletRequest request, HttpServletResponse response) throws Exception {
ServletOutputStream servletOutputStream = null;
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=downloadppt.pptx");
byte[] ppt = downloadFile();
servletOutputStream = response.getOutputStream();
servletOutputStream.write(ppt);
} catch (Exception e) {
throw e;
} finally {
servletOutputStream.flush();
servletOutputStream.close();
}
}
Generate bytes from saved pptx file.
public byte[] downloadFile() throws IOException {
InputStream inputStream = new FileInputStream(new File("e:/testppt.pptx"));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// Transfer bytes from source to destination
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
byteArrayOutputStream.write(buf, 0, len);
}
inputStream.close();
byteArrayOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
That's it, you are able to download pptx file. Hope code help you, if you have any query or doubt then we can discuss or if any suggestions. Thank you

Related

Show content of File

i would like to open/show the file content in a browser but i dosen't work.
This is my code:
#WebServlet("/Download")
public class Download extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String name = request.getParameter("id");
String sep = File.separator;
File file = new File("C:" + sep + "FILE" + sep + name);
if(!file.exists())
{
response.getWriter().print("File not found");
return;
}
InputStream in = new FileInputStream(file);
byte[] buffer = new byte[4096];
int i = 0;
while((i = in.read(buffer)) != -1)
{
baos.write(buffer, 0, i);
}
response.setContentType("application/pdf");
response.setContentLength(baos.size());
response.setHeader("Content-Disposition", "inline; filename=help.pdf");
response.setHeader("Cache-Control", "cache, must-revalidate");
response.setHeader("Pragma", "public");
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
in.close();
baos.writeTo(bos);
baos.flush();
bos.flush();
bos.close();
}
}
I try to open that file with a servlet class.
I browser debugger i can see that response is coming in, usually in this format(JVBERi0xLjMNMSAwIG9iag08PC9UeXBl...).
Thanks for helping me
EDIT
on the jsp site i call the servlet with an AJAX call, looks like this where 'id' is the fileName which the user want to open.
function downloadFile(id) {
$.ajax({
url:"Download",
type:"POST",
data:"id="+id
});
}
i think you should add this code inside your ajax call in downloadFile(id) function.
success:function(response){
$("#<Some_SPAN_OR_TextAreaID>").show();
$("#<Some_SPAN_OR_TextAreaID").html(response.responseText);
}

How to download file in browser using spring mvc?

I have file on the server & that I want to download on my machine using browser. But I am not getting an option from browser to download the file.
My code is
JSP
<div id="jqgrid">
<table id="grid"></table>
<div id="pager"></div>
</div>
JS
jq("#grid").jqGrid({
....
onCellSelect: function(rowid, index, contents, event) {
...
var fileName = jQuery("#grid").jqGrid('getCell',rowid,'fileName');
$scope.downloadFile(fileName);
}
});
$scope.downloadFile = function(fileName) {
$http({
url: "logreport/downLoadFile",
method: "GET",
params: {"fileName": fileName}
});
};
Controller
#RequestMapping(value = "/downLoadFile", method = RequestMethod.GET)
public void downLoadFile(HttpServletRequest request, HttpServletResponse response) {
try {
String fileName = request.getParameter("fileName");
File file = new File(filePath +"//"+fileName);
InputStream in = new BufferedInputStream(new FileInputStream(file));
response.setContentType("application/xlsx");
response.setHeader("Content-Disposition", "attachment; filename="+fileName+".xlsx");
ServletOutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
response.flushBuffer();
} catch (Exception e) {
e.printStackTrace();
}
}
I am not getting any exception but not sure why browser dialog is not opening to download the file. Also where is it exactly downloading the file?
#SotiriosDelimanolis was right. File download is not possible using ajax request.
Simply use 'window.location'.
$scope.downloadFile = function(fileName) {
window.location.href = 'logreport/downLoadFile?fileName=asdad1';
};
I didn't have enough credit to give a comment so wiritting here.. Thanks user1298426. I was strugling like anything for this. I was trying with AJAX. With window.location.href, I can download file in browser...
MY javascript code is as follows:
jQuery('#exportToZip').click(function() {
window.location.href = '*****';
});
*****: is the url mapping that I have in controller.
#RequestMapping(value = "/****")
#ResponseBody
public void downloadRequesthandler(HttpServletRequest request,HttpServletResponse response) {
String status;
try {
filedownloader.doGet(request, response);
} catch (ServletException e) {
status="servlet Exception occured";
e.printStackTrace();
} catch (IOException e) {
status="IO Exception occured";
e.printStackTrace();
}
//return status;
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
// construct the complete absolute path of the file
File downloadFile = new File(filePath);
System.out.println("downloadFile path: "+ filePath);
FileInputStream inputStream = new FileInputStream(downloadFile);
// get MIME type of the file
String mimeType = context.getMimeType(fullPath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}
System.out.println("MIME type: " + mimeType);
response.setContentLength((int) downloadFile.length());
// set headers for the response
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",downloadFile.getName());
response.setHeader(headerKey, headerValue);
OutputStream outStream = response.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
System.out.println("buffer: "+ buffer.length);
int bytesRead = -1;
// write bytes read from the input stream into the output stream
//be carefull in this step. "writebeyondcontentlength" and "response already committed" error is very common here
while ((bytesRead = inputStream.read(buffer))!=-1 ) {
outStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outStream.close();
}
Trying to download file with ajax is a blunder....
cheers......
Instead of using IOUtils copy method
ServletOutputStream out = response.getOutputStream();
IOUtils.copy(in, out);
You can use following :
ServletOutputStream out = response.getOutputStream();
byte[] bytes = IOUtils.toByteArray(in);
out.write(bytes);
out.close();
out.flush();
Hope this will work.

Download multiple files Java

I am using the following code to download a file within the WEB-INF
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String b = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("thecookie")) {
b = cookie.getValue();
}
}
}
BufferedReader br = new BufferedReader(new FileReader(b+"/logs.txt"));
String path = br.readLine();
br.close();
File file = new File(path+"/Results.xlsx");
FileInputStream fileIn = new FileInputStream(file);
ServletOutputStream out = response.getOutputStream();
response.setHeader("Content-Disposition", "attachment; filename=Result.xlsx");
response.setContentType(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
byte[] outputByte = new byte[4096];
int bytesRead;
//copy binary contect to output stream
while((bytesRead = fileIn.read(outputByte)) != -1)
{
out.write(outputByte, 0, bytesRead);
}
fileIn.close();
out.flush();
out.close();
}
along with this I want to download another file at the same location Results.csv I've tried using the same code above twice but it didn't work.
How to download multiple files without using zipoutputstream?
MIME/multipart responses are, as far as I know, not part of the HTTP standard. Some browsers seem to support it, but I recommend against using it.
Instead, you could pack those files into a ZIP file (using a ZipOutputStream), and return that as your response. That's also the way DropBox handles the download of multiple files at once.
It is possible but having them in separate requests if you plan to work within every browser.
Here a sample script for downloading a file via javascript
function downloadFile(url, name) {
var link = document.createElement("a");
link.download = name;
link.href = url;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}
downloadFile(url1,filenam1);
downloadFile(url2,filenam2);
downloadFile(url3,filenam3);
...

how to provide download option for the dynamically generated file in java

I am creating pdf file using jasper reports. The code for generating the pdf file runs fine and the file is created on a specified path. But I want the file to be downloaded rather than to be stored on some drive of a client. I use word dynamically in my question because it is generated from jasper reports when user clicks on download. I googled for this and I got that response.setHeader is responsible for downloading but it needs a source or we can say that path of the storage. The code for generating pdf is given below.
String ip="D:\\workspace\\Jsaper1\\src\\Coll.jasper";
String op="D:\\workspace\\Jsaper1\\src\\Timesheet.pdf";
try
{
File file=new File(ip);
InputStream is=new FileInputStream(file);
Map<String, Object> params = new HashMap<String, Object>();
Datasource da=new Datasource();
JRDataSource jrdsource=new JRBeanCollectionDataSource(da.getDataSource());
JasperReport jreport=(JasperReport) JRLoader.loadObject(file);
JasperPrint jasperPrint = JasperFillManager.fillReport(jreport, params, da.getDataSource1());
JasperExportManager.exportReportToPdfFile(jasperPrint, op);
sos.flush();
sos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
Since the generated file is already written in the disk, you can just open it then write to the response' OutputStream. Use IOUtils#copy from Apache to copy the content of input stream to an output stream avoiding the boilerplate. It also does internal buffering so no need to wrap your InputStream with BufferedInputStream.
public class DownloadServlet extends HttpServlet{
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/octet-stream; charset=windows-1252");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(new File("file-path-where-generated-pdf-is-stored"));
output = response.getOutputStream();
IOUtils.copy(input, output);
output.flush();
} catch (IOException e) {
//log it
} finally{
close(input);
close(output);
input = null;
output = null;
}
}
//Right way to close resource
public static void close(Closeable c) {
if (c == null) return;
try {
c.close();
}catch (IOException e) {
//log it
}
}
}
Here is a solution for you
Insert this code in your html/Interface file. You could do something like this:
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
ServletOutputStream sosStream = response.getOutputStream();
JasperPrint jasperPrint = (JasperPrint) session.getAttribute("jasperPrint");
JasperExportManager.exportReportToPdfStream(jasperPrint, sosStream);
File tempFile = File.createTempFile("TempFile.pdf",".tmp",new File("."));
InputStream isStream = null;
isStream = new FileInputStream(tempFile);
int ibit = 256;
while ((ibit) >= 0)
{
ibit = isStream.read();
sosStream.write(ibit);
}
sosStream.flush();
sosStream.close();
isStream.close();
out.clear();
out = pageContext.pushBody();
Notes :-
1. Response contentype and Header is set.
2. You can set jasperprint in session and retrieve it.
3. JasperExportManager.exportReportToPdfStream is called on the fly. This will take create an outpoutstream of pdf.
4. Rest of the code does writing jobs from stream to temp file.
You can call this code on click action of a button for download and a pop-up for download file will emerge asking for save location.
Try using the below sample as reference
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JRAbstractExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
ByteArrayOutputStream baos = exporter.exportReport();
OutputStream os = null;
try {
response.setContentType(mimeType);
response.setHeader("Content-disposition", "attachment; filename=\"Timesheet.pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
os = response.getOutputStream();
response.setContentLength(baos.size());
baos.writeTo(os);
} finally {
os.flush();
os.close();
}
Please use ByteArrayOutputStream obj in report method , I have implemented in Dynamic report(Jasper Api) , Its working for me :-
#RequestMapping(value="/pdfDownload", method = RequestMethod.GET)
public void getPdfDownload(HttpServletResponse response) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
report().columns().setDataSource().show()
.toPdf(buffer);
byte[] bytes = buffer.toByteArray();
InputStream inputStream = new ByteArrayInputStream (bytes);
IOUtils.copy(inputStream, response.getOutputStream());
response.setHeader("Content-Disposition", "attachment; filename=Accepted1.pdf");
response.flushBuffer();
}
You can use bellow code. Here is complete Example using java servlet
I have add bellow code. you can use bellow code to download pdf file from servlet..
Please download bellow jar file
Please download bellow jar file
1. jasperreports-5.0.1.jar
2. commons-logging-1.1.2.jar
3. commons-digester-2.1.jar
4. commons-collections-3.2.1-1.0.0.jar
5. commons-beanutils-1.8.3.jar
6. groovy-all-2.1.3.jar
7. com.lowagie.text-2.1.7.jar
8. your database library
Now use bellow code in servlet in doGet
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String path = "D:\\Software\\iReport-5.0.0-windows-installer\\u\\report4.jrxml";
JasperReport jasReport = JasperCompileManager.compileReport(path);
System.out.println("Jasper Report : " + jasReport);
//Database connection
Connection con = /*Your Datase Connection*/ ;
System.out.println(con);
//If You have paramerter add here
Map paramMap = new HashMap();
paramMap.put("id", request.getParameter("id"));
//if your have any parmeter add null to paramMap
JasperPrint jasPrint = JasperFillManager.fillReport(jasReport, null, con); //, mapParam, con);
System.out.println("Jasper Print : " + jasPrint);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.setContentType("application/x-download");
response.addHeader("Content-disposition", "attachment; filename=creditcard.pdf");
ServletOutputStream sos = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasPrint, sos);
} catch (JRException ex) {
Logger.getLogger(Tests.class.getName()).log(Level.SEVERE, null, ex);
}
}

HttpServletResponse prompt for file name on save

I used code similar to something below to return a zip file as an attachment to a SpringMVC request. The whole thing works great, I am able to download a file called hello.zip when I make a request to localhost/app/getZip.
My question here is, how can I prompt the user to enter a file name. Currently on FireFox25.0 it automatically assumes the name to be "hello.zip" without the provision to change the file name on Open or Save options.
#RequestMapping("getZip")
public void getZip(HttpServletResponse response)
{
OutputStream ouputStream;
try {
String content = "hello World";
String archive_name = "hello.zip";
ouputStream = response.getOutputStream();
ZipOutputStream out = new ZipOutputStream(ouputStream);
out.putNextEntry(new ZipEntry(“filename”));
out.write(content);
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename="+ archive_name);
out.finish();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
TL;DR: Using HttpServletResponse I want user to provide a file name instead of passing one in the Header.
with method to RequestMethod.GET
URL : http://localhost/app/getZip?filename=hello.zip
#RequestMapping(value = "getZip/{filename}", method = RequestMethod.GET)
public void getZip(HttpServletResponse response, #PathVariable String filename)
{
OutputStream ouputStream;
try {
String content = "hello World";
String archive_name = "hello.zip";
ouputStream = response.getOutputStream();
ZipOutputStream out = new ZipOutputStream(ouputStream);
out.putNextEntry(new ZipEntry("filename"));
out.write(content);
response.setContentType("application/zip");
response.addHeader("Content-Disposition", "attachment; filename="+ archive_name);
out.finish();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}

Categories