4

简而言之:我可以制作一个文件,将其保存在文件系统中,然后制作一个带有指向该文件的链接的页面,但是如果我想要一个带有指向许多可能不需要生成的文件的链接的页面怎么办?

因此,我的用户单击列表页面上的链接,例如:

<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 控制器只提供文件而不是制作带有文件链接的页面吗?

好的,所以澄清一下这是我根据 Kaleb 的回答最终得出的结论。谢谢你这么!!

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

2 回答 2

3

您可以创建一个仅获取文件字节并写入响应的视图:

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

那是你想要做的吗?

于 2011-06-07T22:26:06.907 回答
3

另一个更好的选项,您可以直接从控制器的操作中渲染文件:

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

另见: http: //grails.org/doc/latest/ref/Controllers/render.html

(我发现如果添加fileName选项,它会提示用户下载文件。)

于 2014-07-23T02:04:17.393 回答