Grails Rendering插件保存到文件

时间:2011-05-16 21:23:45

标签: grails rendering grails-plugin

当我显示生成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文件。我试图以与渲染文档描述的完全相同的方式保存到文件。我做错了什么?

4 个答案:

答案 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')

谢谢你们