Grails создает загружаемый файл на лету - PullRequest
4 голосов
/ 08 июня 2011

Вкратце: я могу создать файл, сохранить его в файловой системе, а затем создать страницу со ссылкой на этот файл, но что, если я хочу страницу со ссылками на множество файлов, которые, возможно, не все должны быть сгенерированы?

Итак, мой пользователь нажимает ссылку на странице списка, например:

<g:link action="gimmeAFile" id="${myThingieInstance.id}">${fieldValue(bean: myThingieInstance, field: "id")}</g:link>

Сейчас у меня есть контроллер, который выглядит следующим образом:

def gimmeAFile = {
  def lotsaLines = []
  //Do a ton of stuff that has lotsaLines.add(resultStrings) all over

  def fileName = "blahblah-${dateOrSomething}.csv"
  def dumbFile = new File('web-app/tmpfiles/'+fileName).withWriter {out ->
    lotsaLines.each{
      out.println it
    }
  }
  [fileName:fileName]
}

И затем ониперейдите к gimmeAFile.gsp, на котором есть ссылка для фактической загрузки файла:

<a href="${resource(dir:'tmpfiles',file:fileName)}">Download Report</a>

Как создать ссылку в средстве просмотра списка, которое будет создавать и загружать файл без перетаскивания пользователя на дополнительный экран.ПРИМЕЧАНИЕ. Я не могу предварительно сгенерировать файлы, поэтому мне нужно выяснить, как сделать ссылку на файл, которого там еще нет.Я думаю что-то вроде render () в конце контроллера.Могу ли я заставить контроллер gimmeAFile просто выдавать файл вместо создания страницы со ссылкой на файл?

ОК, чтобы пояснить это, я наконец понял, основываясь на ответе Калеба.Спасибо ТАК !!

def gimmeAFile = {
  def lotsaLines = []
  //Do a ton of stuff that has lotsaLines.add(resultStrings) all over

  def fileName = "blahblah-${dateOrSomething}.csv"
  def dumbFile = new File('web-app/tmpfiles/'+fileName).withWriter {out ->
    lotsaLines.each{
      out.println it
    }
  }
  def openAgain = new File('web-app/tmpfiles/'+fileName)
  response.setContentType("text/csv")
  response.setHeader("Content-disposition", "filename=${fileName}")
  response.outputStream << openAgain.getBytes()
  response.outputStream.flush()
  return
}

Ответы [ 2 ]

3 голосов
/ 23 июля 2014

Еще один вариант, который немного лучше, вы можете просто визуализировать файл прямо из действия вашего контроллера:

render(file: theFile, contentType: 'your/contentType')

Смотри также: http://grails.org/doc/latest/ref/Controllers/render.html

(Я обнаружил, что если вы добавите параметр fileName, он предложит пользователю загрузить файл.)

3 голосов
/ 08 июня 2011

Вы можете создать представление, которое просто получает байты файла и записывает в ответ:

response.contentType  = 'image/jpeg' // or whatever content type your resources are
response.outputStream << file.getBytes()
response.outputStream.flush()

Это то, что вы пытаетесь сделать?

...