开发者

Grails Rendering plugin save to file

I'm trying to use the rendering plugin to save a generated pdf to a file when a controller action to generate a PDF is shown. I'm following the instructions per: 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")
    }

The renderPdf() method works fine, as the output in my browser is what is expected. But when I go look at the created ProjectDocument, I see a blank PDF file. I'm trying to save to a file in the exact same way described by the rendering documentation. What am I doing wrong?


I think this is an error in the docs. Pass your outputStream as the last argument to 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
}


A little late on the game here but the samples in the docs are misleading. I also tried

new File("report.pdf").withOutputStream { outputStream ->
            outputStream << pdfRenderingService.render(template: '/report/report', model: [serial: 12345])
        }

Which created a blank PDF. Mind you it wasn't zero bytes - there was data in the file but it was a blank PDF. The issue is that the method signature takes a map and an output stream whereas the sample shows this:

pdfRenderingService.render(template: '/report/report', model: [serial: 12345])

It should be this :

pdfRenderingService.render([template: '/report/report', model: [serial: 12345]], new File("report.pdf").newOutputStream())

Then your PDF will have content.

I think the sample is trying to show the renderPDF method signature or... ah well who needs samples anyway right?

Hopefully this will help others.


I tried all of the above solutions.. but one thing was missing "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
}

Now you can store it and use it later like 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()


For me its works the next script for 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')

Thanks guys

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜