Return a file from java method - java

I have created a method which accepts the JSON response and export the data to Excel and CSV file. I want the method to accept the filename as a parameter, and return the File/FileHandle object from the method.
Can anyone help me regarding this?
I am using below code to export data from creteExcel and createCSV.
public void createExcel( PageModel pageModelRequest,PageModel pageModelResponse ){
FileOutputStream outputStream=new FileOutputStream(new File("GridData.xlsx"));
createGrid(pageModelResponse, sheet, workbook);
workbook.write(outputStream);
System.out.println("Excel Written");
outputStream.close();
workbook.close();
}
public void createCSV(PageModel pageModelRequest,PageModel pageModelResponse){
String csvFile = "/Users/abhinak4/Desktop/GridData.csv";
FileWriter writer = new FileWriter(csvFile);
createGrid(pageModelRequest, pageModelResponse, writer);
}
In the method createGrid, I am creating the workbook for excel, and I am appending the data, to the writer (writer.append).
I want to know, how can I accept the fileName as parameters for createExcel and createCSV method, and return the file with the same name containing the data?

I want the method to accept the filename as parameter : You can send a String, A File Object or InputStream - createExcel(PageModel req, PageModel resp, File yourFileObj) And return the File object from the method : The signature becomes: public File createExcel()

Use this way and you are able to get a file object
File file = new File(fileName);
FileOutputStream outputStream = new FileOutputStream(file);
workBook.write(outputStream);
My details explanation answer was deleted by someone so I explained here

Related

download csv from filepath in java

I am trying to download csv file from the filepath that is saved in db. I have to read the csv file from filepath and download it when hitting the endpoint. Error I am getting says no converter for class BufferedReader with preset Content-Type 'application-csv'. I think the type I have with response entity BufferedReader is not taking my content-type as csv. I have seen resource type with response entity working fine. And I don't want csv to be generated, I already have it, i just have to read it and download it.
#GetMapping("/export")
public CompletableFuture <ResponseEntity<BufferedReader>> getCSVFile(#RequestParam Integer reportdt,
#RequestParam("conId") String conId) throws IOException {
CSVFilePath csvFilePath = csvFilePathRepository.findByConIdAndReportdt(conId, reportdt);
File file = new File(csvFilePath.getFilepath());
//FileInputStream csvfile = new FileInputStream(csvFilePath.getFilepath());
FileReader newfile = new FileReader(csvFilePath.getFilepath());
String fileName = file.getName();
if(file.exists()) {
return CompletableFuture
.completedFuture(ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName)
.contentType(MediaType.parseMediaType("application/csv"))
.body(new BufferedReader(newfile)));
} else {
return CompletableFuture
.completedFuture(ResponseEntity.status(HttpStatus.NOT_FOUND).body(new BufferedReader(newfile)));
}
}
Here is the error log.
error log

Is there a way to provide file download without reading the file from path in Java?

In my program I have a getRequest (JavaSpark) that offers me an Excel file created in Java for download.
To do this, I create the Excel file, save it in a folder and then read the file via the path.
Works.
Code - ExcelCreation:
public void createPlanWorkbook() throws Exception {
...
...
do something with workbook...
workBook.write("C:\\Users\\Develope\\Desktop\\Excel.xlsm");
}
Code - request:
get("/excelfile", ((request, response) -> {
response.header("Content-disposition", "attachment; filename=Excel.xlsm;");
File file = new File("C:\\Users\\Develope\\Desktop\\Excel.xlsm");
OutputStream outputStream = response.raw().getOutputStream();
outputStream.write(Files.readAllBytes(file.toPath()));
outputStream.flush();
return response;
}));
I wonder if there is another way to implement this. Is the step of saving and then reading the file necessary? Or is there a way to put the file directly from Javaobject into the request.
For example:
outputStream.write(ExcelCreaterObject().getWorkbook());
It seems that you are using Apache POI SmartXls to create an Excel workbook. Looking at its Javadoc, it seems that the Workbook.write method accepts an outputstream to write to.
So, you should be able to do write to the response stream directly, something like:
get("/excelfile", ((request, response) -> {
response.header("Content-disposition", "attachment; filename=Excel.xlsm;");
File file = new File("C:\\Users\\Develope\\Desktop\\Excel.xlsm");
OutputStream outputStream = response.raw().getOutputStream();
// do some stuff with the workbook
workbook.write(outputStream);
return response;
}));

Text File writing in Java

I am writing String content to text file in Java code but after writing saving file onto disk, I am getting Incorrect encoding exception, Please suggest me correct Java Code?
String content =fileContent;//fileContent.toString();
System.out.println("File Contt===>"+content);
File fileWrite = new File("/homeDesktop/NormalFile/"+filename);
// if file doesnt exists, then create it
if (!fileWrite.exists()) {
fileWrite.createNewFile();
}
FileWriter fw = new FileWriter(fileWrite.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(fileContent);
bw.close();
IOUtils.toString(String) Converts your coding.
String not encoded in UTF-8
NOTE:
You dont need this:
// if file doesnt exists, then create it
if (!fileWrite.exists()) {
fileWrite.createNewFile();
}
File create automatically a new file, if there isn't one.

Download CSV file via Rest

Using OpenCSV, I can successfully create a CSV file on disc, but what I really need is to allow users download the CSV with a download button, I don't need to save on disk, just download. Any ideas?
#GET
#Path("/downloadCsv")
public Object downloadCsv() {
CSVWriter writer;
FileWriter wr;
//Or should I use outputstream here?
wr= new FileWriter("MyFile.csv");
writer = new CSVWriter(wr,',');
for (Asset elem: assets) {
writer.writeNext(elem.toStringArray());
}
writer.close();
}
EDIT: I do NOT want to save/read file on disc EVER
To force "save as", you need to set the content disposition HTTP header in the response. It should look like this:
Content-Disposition: attachment; filename="whatever.csv"
It looks like you're using JAX-RS. This question shows how to set the header. You can either write the CSV to the HTTP response stream and set the header there or return a Response object like so:
return Response.ok(myCsvText).header("Content-Disposition", "attachment; filename=" + fileName).build();
You do not need to write to a File object in the middle of this process so can avoid writing to disk.
First, you code cannot be compiled, right? Method downloadCsv() declares return type Object but does not return anything.
I'd change the declaration to String downloadCsv() and return the content of CSV as string. To do this use StringWriter instead of FileWriter and then say return wr.toString().
The only thing that is missing here is content type. You annotate your method as #Produces({"text/csv"}).
I think, that's it.
response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".csv");
response.setContentType("text/csv");
OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
List<String[]> result = iSmsExportService.csvExport(columnNames);
CSVWriter csvWriter = new CSVWriter(osw, ';');
csvWriter.writeAll(result);
csvWriter.flush();
csvWriter.close();
Downloading of CSV file has started after this.

Create and download CSV file in a Java servlet

I am working on Java ExtJS application in which I need to create and download a CSV file.
On clicking a button I want a CSV file to be downloaded to a client's
machine.
On buttons listener I am calling a servlet using AJAX. There I am
creating a CSV file.
I don't want the CSV file to be saved in the server. I want the file should be created dynamically with a download option. I want the contents of a file to be created as a string and then I will serve the content as file in which it will open as download mode in browser (this I have achieved in other language, but not sure how to achieve it in Java).
Here is my code only to create a CSV file, but I really don't want to create or save CSV file if I can only download the file as CSV.
public String createCSV() {
try {
String filename = "c:\\test.csv";
FileWriter fw = new FileWriter(filename);
fw.append("XXXX");
fw.append(',');
fw.append("YYYY");
fw.append(',');
fw.append("ZZZZ");
fw.append(',');
fw.append("AAAA");
fw.append(',');
fw.append("BBBB");
fw.append('\n');
CSVResult.close();
return "Csv file Successfully created";
} catch(Exception e) {
return e.toString();
}
}
Can any one help me on this.
Thanks
I got the solution and I am posting it below.
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=\"userDirectory.csv\"");
try
{
OutputStream outputStream = response.getOutputStream();
String outputResult = "xxxx, yyyy, zzzz, aaaa, bbbb, ccccc, dddd, eeee, ffff, gggg\n";
outputStream.write(outputResult.getBytes());
outputStream.flush();
outputStream.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
Here we don't need to save / store the file in the server.
Thanks
First of all you need to get the HttpServletResponse object so that you can stream a file into it.
Note : This example is something I Wrote for one of my projects and it works.Works on Java 7.
Assuming you got the HttpServletResponse you can do something like this to stream a file. This way the file will be saved into clients' machine.
public void downloadFile(HttpServletResponse response){
String sourceFile = "c:\\source.csv";
try {
FileInputStream inputStream = new FileInputStream(sourceFile);
String disposition = "attachment; fileName=outputfile.csv";
response.setContentType("text/csv");
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);
}
}
And the stream method should be like this.
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;
}
}
What this does is, get an inputstream from your source file and write that stream into the outputstream of the HttpServletResponse. This should work since it works perfectly for me. Hope this helps. Sorry for my bad English.
I would like add something to the answer by gaurav. I recently had to implment this functionality in a project of mine and using javascript was out of the question becuase we had to support IE 9. What is the problem with IE 9?
(Export to CSV using jQuery and html), see the second answer in the link.
I needed an easy way to convert a ResultSet of a database query to a string which represent the the same data in CSV format. For that I used http://opencsv.sourceforge.net/ which provided an easy way to get a String ot of the ResultSet, and the rest is as above answer did it.
THe examples in the project soruce folder give good examples.

Categories

Resources