java - 如何在grails应用程序中创建一个新目录来存储用户可以下载的jasper报告文件

标签 java grails browser jasper-reports download

我想创建一个新目录来存储 jasper 报告生成的所有 pdf 报告,并且用户也应该可以下载它们

例如:我正在导出一个名为“pdfreport20110804788.pdf”的文件。当我将此文件放入该目录时。我在 Controller 方法中设置了某些内容,并且我需要从 groovy 方法返回创建的文件,其中创建新目录并将其导出为 pdf 文件,以便该文件应返回到 Controller 调用方法以进行进一步操作

response.setContentType("application/octet-stream")
response.setHeader("Content-disposition", "attachment;filename=${file.getName()}")
response.outputStream << file.newInputStream()

所以,我一直在尝试这些事情,方法是使用 createTempFile 方法创建文件并将文件返回到 Controller ,但文件被下载到 c:\... 位置,而不要求下载或打开。可以任何一个请给我解决方案

最佳答案

有两件事您需要注意:

1.) 网站上的用户无法直接访问服务器磁盘上生成的文件。您必须通过浏览器通过输出流传送文件。

2.) 您无法自由访问您网站上用户的磁盘。因此,如果您的网站在“c:\website\file.pdf”上创建文件,它将始终转到服务器的“c:”驱动器,而不是最终用户的“c:”驱动器。请记住,“c:\”驱动器主要是 Windows 的东西,因此即使您可以这样做,Unix 或移动用户也无法使用该网站,因为他们没有“c:”驱动器。

所以,如果您想存储文件并允许用户立即或稍后下载它们,我会这样做(未经测试,它可能会更好,但显示了概念)。 .

创建一个代表您的报告目录的类

class ReportDirectory{

   static final String path = "./path/to/reports/"; //<-- generic path on your SERVER!

   static{
       //static initializer to make sure directory gets created.  Better ways to do this but this will work!

       File pathAsFile = new File(path).mkdirs()

       if (pathAsFile.exists()){
          println("CREATED REPORT DIRECTORY @ ${pathAsFile.absolutePath}");
       }else{
          println("FAILED TO CREATE REPORT DIRECTORY @ ${pathAsFile.absolutePath}");
       }

   }

   public static File[] listFiles(){
       return new File(path).listFiles(); //<-- maybe use filters to just pull pdfs?
   }

   public static void addFile(File file){
       FilesUtil.copyFileToDirectory(file, new File(path)); //<-- using apache-commons-io
   }

   public static void deleteAll(){
       listFiles().each(){ fileToDelete ->
           fileToDelete.delete();
       }
   }

   public static File findFile(String name){
       listFiles().each(){ fileToCheck ->

           if (fileToCheck.name.equals(name)){
               return fileToCheck
           }
       }
       return null
   }

}

然后在你的 Controller 中你可以做这样的事情......

class ReportController{

   def runReport = {
       File report = createReport() //<-- your method to create a report.
       ReportDirectory.addFile(report);

       redirect(action:"downloadFle" params:[fileName:report.name])

   }    


   def showAllFiles = {
       [files:ReportDirectory.listFiles()]
   }

   def downloadFile = {
      def fileName = params.fileName;

      def fileToDownload = ReportDirectory.findFile(fileName);

      if (fileToDownload){

      response.setContentType("application/octet-stream")
      response.setHeader("Content-disposition", "attachment;filename=${fileToDownload .getName()}")
      response.outputStream << fileToDownload.newInputStream()  //<-- ask the user to download
     }else{
         //handle when the file is not found
     }

   }

   def deleteAllFiles ={
       ReportDirectory.deleteAllFiles()

       [files:ReportDirectory.listFiles()] //<-- return the remaining files, if any.
   }


}

关于此解决方案的一些评论...

- 这不解决 MIME 类型,因此浏览器将无法确定通过网络传输的二进制数据类型。

这有帮助吗?

关于java - 如何在grails应用程序中创建一个新目录来存储用户可以下载的jasper报告文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6772350/

相关文章:

browser - 容易自动换行的字符

html - 如何为所有主要浏览器禁用自动完成

Java,类中的For循环

javascript - 在哪里以及如何保存 token JWT? (最佳实践)

java - 如何正确子类 SimpleCameraHost 以在 caac-camera 中使用?

Grails/GORM 映射到非标准命名的外键

grails - 从Quartz Job访问config.groovy变量

grails - groovy中的多文件访问(Groovy on Grails)

java - 在 OpenJPA 中合并树状结构?

java - 如何在 robolectric 测试中添加一些一次性启动代码