Как создать новый каталог в приложении Grails для хранения файлов отчетов Jasper, которые могут быть загружены пользователем - PullRequest
0 голосов
/ 21 июля 2011

Я хочу создать новый каталог для хранения всех отчетов pdf, сгенерированных отчетами jasper, и они также должны быть доступны для загрузки пользователями

Например: я экспортирую файл с именем "pdfreport20110804788.pdfmsgstr "Когда я помещаю этот файл в этот каталог. Я устанавливаю определенные вещи в методе контроллера, и мне нужно, чтобы созданный файл был возвращен из метода groovy, в котором создается новый каталог, и он экспортируется как файл PDF, так что файл должен быть возвращен".в метод вызова контроллера для дальнейших операций

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

Итак, я пытался это сделать, создав файл с помощью метода createTempFile и вернув файл в контроллер, но файл загружался в c: \... местоположение, не спрашивая, чтобы загрузить или открыть. Может кто-нибудь, пожалуйста, дайте мне решение для этого

1 Ответ

5 голосов
/ 21 июля 2011

Вам необходимо знать о двух вещах:

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
   }

}

Тогда в вашем контроллере вы можете делать такие вещи ...

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, поэтому браузер не сможет определить, какие двоичные данные поступают по проводам.

это полезно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...