如何使用导出插件在 Grails 中生成多个报告?
How to generate multiple reports in Grails using Export plugin?
我正在使用 Grails 中的 Export plugin 生成 PDF/Excel 报告。我能够在 PDF/Excel 按钮点击时生成单个报告。但是,现在我想在单击一次按钮时生成多个报告。我尝试了循环、方法调用,但没有成功。
参考链接没问题。我不期望完整的代码,仅供参考。
如果您查看插件中 ExportService 的源代码,您会发现有多种 export
方法。其中两个支持 OutputStream
s。使用这些方法中的任何一种(取决于您对其他参数的要求)将允许您将报告呈现到输出流。然后使用这些输出流,您可以创建一个 zip 文件,您可以将其传送到 HTTP 客户端。
这是一个非常粗略的示例,它是我随手写的,所以它实际上只是一个想法而不是工作代码:
// 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()
这应该会让您了解如何处理这个问题。同样,以上仅用于演示目的,不是生产就绪代码,我什至没有尝试编译它。
我正在使用 Grails 中的 Export plugin 生成 PDF/Excel 报告。我能够在 PDF/Excel 按钮点击时生成单个报告。但是,现在我想在单击一次按钮时生成多个报告。我尝试了循环、方法调用,但没有成功。
参考链接没问题。我不期望完整的代码,仅供参考。
如果您查看插件中 ExportService 的源代码,您会发现有多种 export
方法。其中两个支持 OutputStream
s。使用这些方法中的任何一种(取决于您对其他参数的要求)将允许您将报告呈现到输出流。然后使用这些输出流,您可以创建一个 zip 文件,您可以将其传送到 HTTP 客户端。
这是一个非常粗略的示例,它是我随手写的,所以它实际上只是一个想法而不是工作代码:
// 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()
这应该会让您了解如何处理这个问题。同样,以上仅用于演示目的,不是生产就绪代码,我什至没有尝试编译它。