简体   繁体   English

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

[英]How to create a new directory in grails application to store jasper report files those can be downloaded by user

I want to create a new directory to store all pdf reports generated by jasper reports and they should be accessible to users to download as well我想创建一个新目录来存储由 jasper 报告生成的所有 pdf 报告,用户也应该可以下载它们

For example: I am exporting the a file called "pdfreport20110804788.pdf".when i put this file in that directory.i set certain things in controller method and i need the file created to be returned from the groovy method where the new directory is created and its is exported as pdf file so that file should be returned to the controller calling method for further operations例如:我正在导出一个名为“pdfreport20110804788.pdf”的文件。当我把这个文件放在那个目录中时。我在 controller 方法中设置了某些东西,我需要创建的文件从 groovy 方法返回,其中新目录是创建并将其导出为 pdf 文件,以便将文件返回到 controller 调用方法以进行进一步操作

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

So,i have been trying these thing by creating the file using the createTempFile method and returning the file to the controller but the file was getting downloaded to c:\... location without asking to download or open.can any one please give me the solution for this所以,我一直在尝试通过使用 createTempFile 方法创建文件并将文件返回到 controller 但文件被下载到 c:\... 位置而不要求下载或打开。任何人都可以给我解决方案

There are two things you need to be aware of:您需要注意两点:

1.) Files generated on the server's disk cannot be directly accessed by a user on your web site . 1.)您的 web 站点上的用户无法直接访问服务器磁盘上生成的文件 You have to deliver the files through the browser via an output stream.您必须通过浏览器通过 output stream 传递文件。

2.) You cannot freely access the disk of a user on your web site . 2.)您不能在 web 站点上自由访问用户的磁盘 So, if your web site creates a file on "c:\website\file.pdf" it will always go to the server's "c:" drive and never to the end users "c:" drive.因此,如果您的 web 站点在“c:\website\file.pdf”上创建一个文件,它将始终 go 到服务器的“c:”驱动器,而不是最终用户“c:”驱动器。 Remember the "c:\" drive is mostly a Windows thing so Unix or mobile users would NOT be able to use the site even if you could do this because they don't have a "c:" drive.请记住,“c:\”驱动器主要是 Windows 的东西,因此 Unix 或移动用户将无法使用该站点,即使您可以这样做,因为他们没有“c:”驱动器。

so, here is what i would do if you want to store the files and allow the user to download them now or later ( not tested and it could be better but shows the concept )...所以,如果你想存储文件并允许用户现在或以后下载它们,我会这样做(未经测试,它可能会更好,但显示了概念)......

create a class that represents your directory of reports创建一个代表您的报告目录的 class

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
   }

}

Then in your controller you could do things like this....然后在你的 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.
   }


}

A few comments about this solution...关于这个解决方案的一些评论......

-this doesn't address MIME types so the browser won't be able to figure out what kind of binary data is coming over the wire. - 这不涉及 MIME 类型,因此浏览器将无法确定通过网络传输的二进制数据类型。

is this helpful?这有帮助吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM