0

I have been trying unsuccessfully for a while to download a CSV file to the browser in grails. I have the data in bytes and am using the following code with no luck... I have tried several options like a Render, but nothing seems to be working for me. Are there any suggestions?

response.contentType='text/csv';
            response.setHeader("Content-Transfer-Encoding", "binary");
            response.setHeader("Cache-Control", "no-cache, must-revalidate");
            response.setHeader("Pragma", "no-cache");
            response.setCharacterEncoding("UTF-8")
            response.outputStream << data.bytes
            response.outputStream.flush();

Sidenote: I have successfully emailed the bytes and they open properly as a CSV file

  • Are you looking to prompt the user to save the file (or open it in an external application) rather than allow the browser to open it? If so, try: `response.setHeader("Content-disposition", "attachment; filename=\"my_file.csv\"")` – Andrew Oct 14 '14 at 15:26
  • @AndrewvonDollen I tried to add this in but still no luck. It doesn't prompt me to download. I've tried in several browsers as well – Mark Goldberg Oct 14 '14 at 15:32
  • Hmm, one more suggestion: It may not be necessary to include the Content-Transfer-Encoding header (see http://stackoverflow.com/a/7289434/513321) – Andrew Oct 14 '14 at 15:46
  • @AndrewvonDollen Unfortunately still not working. I have no idea what it could be. Appreciate the help though. – Mark Goldberg Oct 14 '14 at 16:20
  • I also seem to remember this being a bit fiddly... Take a look at the source for [AttachmentableController](http://svn.codehaus.org/grails-plugins/grails-attachmentable/trunk/grails-app/controllers/com/macrobit/grails/plugins/attachmentable/controllers/AttachmentableController.groovy)'s `download` method - I know for a fact that this works... – rcgeorge23 Oct 14 '14 at 17:35

1 Answers1

0

Try wrapping your byte[] as a stream:

response.outputStream << new ByteArrayInputStream(data.bytes)

A more complete example that works for me:

        try {
            ByteArrayInputStream inStream = new ByteArrayInputStream(data.bytes)
            response.setContentType("text/csv")
            //response.contentLength = data.bytes.length // optional, I think lets browser show progress?
            response.setHeader("Content-disposition", "attachment;filename=data.csv")
            // response.setHeader("Cache-Control", "no-transform") // Disable compression on the output          
            response.outputStream << inStream
        }
        finally {
            inStream.close()
        }
Steve
  • 1,457
  • 12
  • 25