简单来说:我可以创建一个文件,将其保存在文件系统中,然后创建一个包含指向该文件链接的页面,但是如果我想要一个包含许多文件链接的页面,这些文件可能不需要全部生成怎么办?
因此,我的用户在列表页面上点击一个链接,比如:
如何在列表查看器上创建一个链接,以便创建并下载文件,而不会将用户拖到额外的屏幕。注意:我不能预先生成文件,因此我需要想出如何链接到尚不存在的文件。我认为可以在控制器的末尾使用render()之类的东西。我能否让gimmeAFile控制器直接提供文件而不是创建一个带有文件链接的页面?
好的,为了澄清,这是我基于Kaleb的答案最终找到的解决方案。非常感谢!
因此,我的用户在列表页面上点击一个链接,比如:
<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
}
file.bytes
更加时髦! - rodvlopes