2011-05-16 3 views
2

J'essaie d'utiliser le plugin de rendu pour enregistrer un fichier PDF généré dans un fichier lorsqu'une action du contrôleur pour générer un fichier PDF est affichée. Je en suivant les instructions par: http://gpc.github.com/grails-rendering/docs/manual/index.htmlGrails Rendering plugin enregistrer dans le fichier

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") 
    } 

La méthode renderPdf() fonctionne très bien, comme la sortie dans mon navigateur est ce qu'on attend. Mais quand je regarde le ProjectDocument créé, je vois un fichier PDF vide. J'essaye d'enregistrer dans un fichier de la même manière que celle décrite par la documentation de rendu. Qu'est-ce que je fais mal?

+0

Avez-vous déjà eu ce travail? –

Répondre

1

Je pense que c'est une erreur dans les docs. Passez votre outputStream comme dernier argument à 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 
} 
+0

Vous êtes peut-être sur la bonne voie, mais pas exactement. Maintenant, je reçois [email protected] dans un fichier texte vide attaché au document. Avant d'avoir un PDF vierge. –

+0

Ce qui précède enregistre le PDF en tant que fichier sur le disque. Si vous voulez que le contenu du PDF sous la forme d'un tableau d'octets entre dans la colonne 'fileData' de votre tableau, essayez' new ByteArrayOutputStream(). WithStream {outputStream -> ...} ' – ataylor

+0

Vrai, je viens de me rendre compte que c'est plus qu'un peu redondant pour écrire les données d'octets dans un fichier, puis lire dans ce fichier et obtenir les octets à stocker dans une table. Cependant, si je remplace la création/manipulation de fichier par def bytes = "" dans la documentation, je reçois toujours un fichier vide. –

1

Un peu en retard sur le jeu ici, mais les échantillons dans les docs sont trompeuses. J'ai également essayé

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

Qui a créé un PDF vierge. Rappelez-vous que ce n'était pas zéro octet - il y avait des données dans le fichier mais c'était un PDF vierge. Le problème est que la signature de méthode prend une carte et un flux de sortie alors que l'échantillon montre ceci:

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

Il devrait être ceci:

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

Ensuite, votre PDF aura le contenu.

Je pense que l'échantillon essaie d'afficher la signature de la méthode renderPDF ou ... ah bien, qui a besoin d'échantillons, n'est-ce pas?

Espérons que cela aidera les autres.

1

J'ai essayé toutes les solutions ci-dessus .. mais une chose qui manquait "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 
} 

Maintenant, vous pouvez stocker et utiliser plus tard comme ceci:

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() 
1

pour moi, ses œuvres le script suivant pour 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') 

Merci les gars