Create and download CSV file in a Java servlet

68,354

Solution 1

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

Solution 2

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.

Share:
68,354
Gourav
Author by

Gourav

Started my journey now, don't know how much it will take to reach the destination..... Enjoying Journey....

Updated on November 20, 2020

Comments

  • Gourav
    Gourav over 3 years

    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

  • Gourav
    Gourav over 10 years
    If CSV file is created and stored in the server, then above method will work. I appreciate your answer and thanks. It definitely works. But my need was some thing different. I got the solution and posting it.
  • Moob
    Moob almost 9 years
    what is model.closeConnection() in this example? I don't see any object called model.
  • Gourav
    Gourav almost 9 years
    Here model is just a name of the object which will call the closeConnection() function to close the db connection. This is only to make sure that connection is closed. You can place it anywhere in your code as per your design.
  • Moob
    Moob almost 9 years
    Okay. Just wondering wether it should be included in your example? The OP makes no mention of a database connection. It could confuse others as it did me. Just sayin' ;)
  • progNewbie
    progNewbie almost 8 years
    I tried your code but it does not work for me. How do you do the ajax-call? I just did $.get( "SERVLETNAME", { parameters }, function( ) {});
  • pigobyte
    pigobyte over 2 years
    Hi Gourav! .. your solution is perfect but I have two questions: 1) The file I have to download must be a TXT and must have more rows. 2) If I call the servlet from the browser it works but if I use a "post" call with AJAX I only recover the text and does not automatically download the file. Can you explain to me where I'm wrong? Thank you