I should download a csv file from the server through browser.
I try with servlet with following code
private void writeFile(String filename, String content, HttpServletResponse response) throws IOException {
String filename="VR.csv";
try {
File file = new File(filename);
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.flush();
bw.close();
}
catch(IOException e) {
e.printStackTrace();
}
// This should send the file to browser
ServletOutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(filename);
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.flush();
System.out.println("done");
}
But the program doesn't download any file in Download folder, program let me see in the browser the csv content. I need to have the VR.csv in the download folder of the browser.
You are not setting your response! If you want to download an specific file you need to specific in the response what type are you downloading and the path of the specific file.
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment;filename=yourFileName.csv");
In addition to previous answer, your method should have return type, like it should have ModelAndView if you use Spring Framework as follows
public ModelAndView writeFile(String filename, String content, HttpServletResponse response) throws IOException {}
Related
I have a file txt on the server (previously generated). When user clicks on button it generates the file, now I want (additionally) download the file inside my function. But I can't make it work(I'm new on JAVA EE), cause I don't know how to get HttpServletResponse.
From web I call function with this:
#Path("getreport")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public JSONObject getreport(CommonInput input) {
JSONObject j = objectmapper.conertValue(reportBean.getreport(),JSONObject.class);
return j;
}
reprotBean has function:
public void getreport() {
//...doing many things
//generating my file
List<String> lines = new ArrayList<>();
lines.add("star file");
//..adding many lines
Path file = Paths.get("C:\\Users\\myuser\\file.txt");
Files.write(file, lines, StandardCharsets.UTF_8);
downloadFile();
//...doing many things
}
I found this way to download my file:
public void downloadFile(HttpServletResponse response){
String sourceFile = ""C:\\Users\\myuser\\file.txt"";
try {
FileInputStream inputStream = new FileInputStream(sourceFile);
String disposition = "attachment; fileName=outputfile.txt";
response.setContentType("text/txt");
response.setHeader("Content-Disposition", disposition);
response.setHeader("content-Length", String.valueOf(stream(inputStream, response.getOutputStream())));
} catch (IOException e) {
logger.error("Error occurred while downloading file {}",e);
}
}
private long stream(InputStream input, OutputStream output) throws IOException {
try (ReadableByteChannel inputChannel = Channels.newChannel(input); WritableByteChannel outputChannel = Channels.newChannel(output)) {
ByteBuffer buffer = ByteBuffer.allocate(10240);
long size = 0;
while (inputChannel.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
return size;
}
}
When I try to use downloadFile(), it requires HttpServletResponse, and I don't have that parameter. I can't understand how to get that (how it works), or do I have to use another method for download my file?
All solutions I found requires HttpServletResponse (download files from browsers)
If you have that file generated already. Just need write it to HttpServletResponse
resp.setContentType("text/plain");
resp.setHeader("Content-disposition", "attachment; filename=sample.txt");
try(InputStream in = req.getServletContext().getResourceAsStream("sample.txt");
OutputStream out = resp.getOutputStream()) {
byte[] buffer = new byte[ARBITARY_SIZE];
int numBytesRead;
while ((numBytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, numBytesRead);
}
}
Be sure to make your file to be accessed by ServeletContext
If you are using Spring Rest framework. Can refer to below
#GetMapping("/download")
public ResponseEntity<byte[]> downloadErrorData() throws Exception {
List<Employee> employees = employeeService.getEmployees();
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(employees);
byte[] isr = json.getBytes();
String fileName = "employees.json";
HttpHeaders respHeaders = new HttpHeaders();
respHeaders.setContentLength(isr.length);
respHeaders.setContentType(new MediaType("text", "json"));
respHeaders.setCacheControl("must-revalidate, post-check=0, pre-check=0");
respHeaders.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
return new ResponseEntity<byte[]>(isr, respHeaders, HttpStatus.OK);
}
credit to: https://www.jeejava.com/file-download-example-using-spring-rest-controller/
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 have the below code got from mkyong, to zip files on local. But, my requirement is to zip files on server and need to download that. Could any one help.
code wrote to zipFiles:
public void zipFiles(File contentFile, File navFile)
{
byte[] buffer = new byte[1024];
try{
// i dont have idea on what to give here in fileoutputstream
FileOutputStream fos = new FileOutputStream("C:\\MyFile.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze= new ZipEntry(contentFile.toString());
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(contentFile.toString());
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
//remember close it
zos.close();
System.out.println("Done");
}catch(IOException ex){
ex.printStackTrace();
}
}
what could i provide in fileoutputstream here? contentfile and navigationfile are files i created from code.
If your server is a servlet container, just write an HttpServlet which does the zipping and serving the file.
You can pass the output stream of the servlet response to the constructor of ZipOutputStream and the zip file will be sent as the servlet response:
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
Don't forget to set the response mime type before zipping, e.g.:
response.setContentType("application/zip");
The whole picture:
public class DownloadServlet extends HttpServlet {
#Override
public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=data.zip");
// You might also wanna disable caching the response
// here by setting other headers...
try ( ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()) ) {
// Add zip entries you want to include in the zip file
}
}
}
Try this:
#RequestMapping(value="download", method=RequestMethod.GET)
public void getDownload(HttpServletResponse response) {
// Get your file stream from wherever.
InputStream myStream = someClass.returnFile();
// Set the content type and attachment header.
response.addHeader("Content-disposition", "attachment;filename=myfilename.txt");
response.setContentType("txt/plain");
// Copy the stream to the response's output stream.
IOUtils.copy(myStream, response.getOutputStream());
response.flushBuffer();
}
Reference
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();
}
}
I am tryig to make a song available for download on my website. I am using a download servlet that I have used before to make zip files available for download. I have run through the code and everything appears to be working, the output stream reads the entire file but the save dialog box does not appear. Any ideas? Thanks for your help. Code is as follows:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String song = request.getParameter("song");
StringBuilder filePath = new StringBuilder();
try {
Thread.sleep(1);
String[] info = getSongInfo(song);
filePath.append("D:\\My Music\\My Song.m4a");
File file = new File(filePath.toString());
if (!file.exists()) {
throw new FileNotFoundException(file.getAbsolutePath());
}
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Type", "audio/mp4a-latm");
response.setHeader("Content-disposition", "attachment; filename="+song+".m4a");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
byte[] buf = new byte[4096];
while (true) {
int length = bis.read(buf);
if (length == -1) {
break;
}
bos.write(buf, 0, length);
}
bos.flush();
bos.close();
bis.close();
} catch (InterruptedException e) {
System.err.println("Error message: " + e.getMessage());
}
}
Called using:
dojo.xhrGet(
{
url: "/downloadSong?song="+item.title[0]
});
You cannot download files by ajax. JavaScript has due to security reasons no facility to spawn a Save As dialogue nor to store them in disk. It will consume the response, but it can't do anything sensible with it.
You need to use window.location instead:
window.location = "/downloadSong?song=" + item.title[0];
Thanks to the Content-Disposition: attachment header, it won't affect the currently opened page.