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

n92*_*n92 0 java browser grails download jasper-reports

我想创建一个新目录来存储由jasper报告生成的所有pdf报告,用户也可以访问它们以供下载

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

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

所以,我一直在尝试使用createTempFile方法创建文件并将文件返回到控制器,但文件被下载到c:\ ...位置而不要求下载或打开.can任何人请给我解决方案

Mic*_*Lee 5

您需要注意两件事:

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
   }

}
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器中你可以做这样的事情....

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.
   }


}
Run Code Online (Sandbox Code Playgroud)

关于这个解决方案的几点评论......

- 这不涉及MIME类型,因此浏览器将无法确定哪种二进制数据通过网络传输.

这有用吗?

  • 我更新了我的答案,包括一个应该适用于任何操作系统的报告文件夹的通用路径.我还添加了一个静态初始化程序,以确保任何操作系统上都存在报告目录...检查出来 (2认同)