Grails Programmer : How to output CSV from a Grails 3 Controller
% grails -version
Grails Version: 3.1.11
| Groovy Version: 2.4.7
| JVM Version: 1.8.0_45
Create an app with the default web profile.
grails create-app csv
Application created at /Users/groovycalamari/Documents/tests/csv
Enter the grails console
% cd csv
% grais
Create a domain class
grails> create-domain-class Book
| Created grails-app/domain/csv/Book.groovy
| Created src/test/groovy/csv/BookSpec.groovy
Add a couple of properties to the domain class
package cvs
class Book {
String title
String author
static constraints = {
}
}
In grails-app/init/BootStrap.groovy add a couple of domain class instances. The BootStrap init closure runs when the app starts.
import csv.*
class BootStrap {
def init = { servletContext ->
new Book(title: 'Groovy for Domain-Specific Languages', author: 'Fergal Dearle').save()
new Book(title: 'Programming Groovy 2: Dynamic Productivity for the Java Developer', author: 'Venkat Subramaniam').save()
}
def destroy = {
}
}
Create a controller
$ grails
Enter a command name to run. Use TAB for completion:e...
grails> create-controller Book
| Created grails-app/controllers/csv/BookController.groovy
| Created src/test/groovy/csv/BookControllerSpec.groovy
This is the controller content:
package csv
import grails.config.Config
import grails.core.support.GrailsConfigurationAware
import static org.springframework.http.HttpStatus.OK
class BookController implements GrailsConfigurationAware {
String csvMimeType
String encoding
def index() {
final String filename = 'book.csv'
def lines = Book.findAll().collect { [it.title, it.author].join(';') } as List<String>
def outs = response.outputStream
response.status = OK.value()
response.contentType = "${csvMimeType};charset=${encoding}";
response.setHeader "Content-disposition", "attachment; filename=${filename}"
lines.each { String line ->
outs << "${line}\n"
}
outs.flush()
outs.close()
}
@Override
void setConfiguration(Config co) {
csvMimeType = co.getProperty('grails.mime.types.csv', String, 'text/csv')
encoding = co.getProperty('grails.converters.encoding', String, 'UTF-8')
}
}
Several things about the above code.
A) I will recommend to put the logic fetching the lines in a Service. B) I am using the mime type and encoding defined in application.yml. Learn more about retrieving config values. C) If you want the file to download you need to setup the Content-disposition header.
If we run the app and call the controller we will download a CSV file as this:
CSV is probably the best format to export your data from a Grails App. A CSV file is easy to import in Excel. I was tired of my clients asking me how to import a CSV in Excel. I wrote a post; in Spanish though.
Tags: #grails