当我显示生成PDF的控制器操作时,我正在尝试使用渲染插件将生成的pdf保存到文件中。我按照说明:http://gpc.github.com/grails-rendering/docs/manual/index.html
def pdf = {
def project = Project.get(params.id)
def numGoodMilestones = queryService.getGoodShapeMilestonesCount(project)
def totalMilestones = project.milestones.size()
def updateHistory = queryService.getReadableHistory(project)
def summaryName = "${project.name.replace(" ","_")}_summary_${String.format('%tF', new Date()).replace(" ","_")}"
if(!project)
{
flash.message = g.message(code:'default.not.found.message',
args:[message(code:'project.label',default:'Project'),params.id])
redirect(uri:'/')
}
// see if a summary has been generated with this data and attached to the
// project. If not, do it.
def existingAttachedSummary = ProjectDocument.findByName(summaryName)
if(!existingAttachedSummary)
{
//make the file
def savedSummary = new File(summaryName).withOutputStream { outputStream ->
pdfRenderingService.render( controller:this,
template: "projectDetail",
model:[project:project,
numGoodMilestones:numGoodMilestones,
totalMilestones:totalMilestones,
updateHistory: updateHistory])
}
def projectDocument = new ProjectDocument(name:summaryName,
description:"Project summary automatically generated on ${new Date()}}",
fileData:savedSummary,
owner: springSecurityService.currentUser,
project:project
)
if(projectDocument.validate())
{
projectDocument.save(flush:true)
flash.message="I saved a document, yo. ${projectDocument}."
}
else
{
flash.message="Errors, yo. ${projectDocument.errors.allErrors.each{ it }}."
}
}
else
{
flash.message = "project summary already attached to project"
}
renderPdf(template: "projectDetail",
model:[project:project, numGoodMilestones:numGoodMilestones, totalMilestones:totalMilestones, updateHistory: updateHistory],
filename: "${summaryName}.pdf")
}
renderPdf()方法工作正常,因为浏览器中的输出是预期的。但是当我查看创建的ProjectDocument时,我看到一个空白的PDF文件。我试图以与渲染文档描述的完全相同的方式保存到文件。我做错了什么?
答案 0 :(得分:1)
我认为这是文档中的错误。将outputStream作为pdfRenderingService.render
的最后一个参数传递。
def savedSummary = new File(summaryName).withOutputStream { outputStream ->
pdfRenderingService.render( controller:this,
template: "projectDetail",
model:[project:project,
numGoodMilestones:numGoodMilestones,
totalMilestones:totalMilestones,
updateHistory: updateHistory],
outputStream) // <- added this parameter
}
答案 1 :(得分:1)
这里的比赛有点晚,但文档中的样本有误导性。我也试过
new File("report.pdf").withOutputStream { outputStream ->
outputStream << pdfRenderingService.render(template: '/report/report', model: [serial: 12345])
}
其中创建了一个空白PDF。请注意,它不是零字节 - 文件中有数据,但它是一个空白的PDF。问题是方法签名采用地图和输出流,而示例显示:
pdfRenderingService.render(template: '/report/report', model: [serial: 12345])
应该是这样的:
pdfRenderingService.render([template: '/report/report', model: [serial: 12345]], new File("report.pdf").newOutputStream())
然后你的PDF将有内容。
我认为样本试图显示renderPDF方法签名或者......啊,谁还需要样本呢?
希望这会有所帮助。
答案 2 :(得分:1)
我尝试了所有上述解决方案..但有一件事是缺少“toByteArray()”:
def mypdf = new ByteArrayOutputStream().withStream { outputStream ->
pdfRenderingService.render(
[controller:this,
template: "pdf",
model:[form:formInstance]],
outputStream // <- ataylor added this parameter
).toByteArray() // <- I added this
}
现在你可以存储它并在以后像这样使用它:
response.contentType = 'application/pdf'
response.setHeader 'Content-disposition', "attachment; filename=\"${formInstance.name}.pdf\"" // comment this to open in browser
response.outputStream << mypdf
response.outputStream.flush()
答案 3 :(得分:1)
对我来说,它的工作是grails 2.5.0的下一个脚本
// Render to a file
// rendering 2.5.0
def pdf = new ByteArrayOutputStream().withStream { outputStream ->
pdfRenderingService.render(
[controller:this,
template: "printReporte",
model: [reporteCufinInstance: reporteCufinInstance, numAnios: columnas]],
outputStream // <- in the documentation use the outputstream http://gpc.github.io/grails-rendering/guide/single.html#5.%20Rendering%20To%20The%20Response
).toByteArray() // <- parse to byteArray for render file
}
render(file:pdf,contentType: 'application/pdf')
谢谢你们