7

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

Spring
  • 11,333
  • 29
  • 116
  • 185

3 Answers3

19

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.

Community
  • 1
  • 1
tom
  • 2,704
  • 16
  • 28
  • 2
    I've updated my answer. One easy way is to get the string out of the CSVWriter. I use JacksonCSV not OpenCSV, but I imagine it's fairly easy. You could use a StringWriter instead of a FileWriter for example. – tom Feb 19 '14 at 10:21
  • 1
    Yup. Just write it to a string not the file. Return a Response not an Object. Try it out. – tom Feb 19 '14 at 10:25
4

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.

AlexR
  • 114,158
  • 16
  • 130
  • 208
  • if I return a string then will user get a browser save/open dialog box? thats what i need – Spring Feb 19 '14 at 09:44
  • It depends on configuration and type of user's browser. But the return type of method does not affect this process. The content type does. – AlexR Feb 19 '14 at 10:32
  • As fare as I know default behavior of IE is to ask user where to store the file being downloaded. – AlexR Feb 19 '14 at 14:24
4
            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.

Reeebuuk
  • 1,363
  • 2
  • 21
  • 42