VVB
VVB

Reputation: 7641

How to generate multiple reports in Grails using Export plugin?

I am using the Export plugin in Grails for generating PDF/Excel report. I am able to generate single report on PDF/Excel button click. But, now I want to generate multiple reports on single button click. I tried for loop, method calls but no luck.

Reference links are ok. I don't expect entire code, needs reference only.

Upvotes: 0

Views: 1094

Answers (1)

Joshua Moore
Joshua Moore

Reputation: 24776

If you take a look at the source code for the ExportService in the plugin you will notice there are various export methods. Two of which support OutputStreams. Using either of these methods (depending on your requirements for the other parameters) will allow you to render a report to an output stream. Then using those output streams you can create a zip file which you can deliver to the HTTP client.

Here is a very rough example, which was written off the top of my head so it's really just an idea rather than working code:

// Assumes you have a list of maps.
// Each map will have two keys.
// outputStream and fileName
List files = []

// call the exportService and populate your list of files
// ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
// exportService.export('pdf', outputStream, ...)
// files.add([outputStream: outputStream, fileName: 'whatever.pdf'])

// ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream()
// exportService.export('pdf', outputStream2, ...)
// files.add([outputStream: outputStream2, fileName: 'another.pdf'])

// create a tempoary file for the zip file
File tempZipFile = File.createTempFile("temp", "zip")
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(tempZipFile))

// set the compression ratio
out.setLevel(Deflater.BEST_SPEED);

// Iterate through the list of files adding them to the ZIP file
files.each { file ->
    // Associate an input stream for the current file
    ByteArrayInputStream input = new ByteArrayInputStream(file.outputStream.toByteArray())

    // Add ZIP entry to output stream.
    out.putNextEntry(new ZipEntry(file.fileName))

    // Transfer bytes from the current file to the ZIP file
    org.apache.commons.io.IOUtils.copy(input, out);

    // Close the current entry
    out.closeEntry()

    // Close the current input stream
    input.close()
}

// close the ZIP file
out.close()

// next you need to deliver the zip file to the HTTP client
response.setContentType("application/zip")
response.setHeader("Content-disposition", "attachment;filename=WhateverFilename.zip")
org.apache.commons.io.IOUtils.copy((new FileInputStream(tempZipFile), response.outputStream)
response.outputStream.flush()
response.outputStream.close()

That should give you an idea of how to approach this. Again, the above is just for demonstration purposes and isn't production ready code, nor have I even attempted to compile it.

Upvotes: 1

Related Questions