2011-05-16 79 views
2

我试图使用渲染插件将生成的PDF保存到文件,当控制器操作生成PDF时显示。我下面按照指示:http://gpc.github.com/grails-rendering/docs/manual/index.htmlGrails渲染插件保存到文件

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

你有没有得到这个工作? – 2012-07-04 17:41:37

回答

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 
} 
+0

你可能走在正确的轨道上,尽管不完全。现在我将[email protected]放在一个附在文档中的空白文本文件中。在我得到一个空白的PDF之前。 – 2011-05-16 23:00:24

+0

上面将PDF保存为文件到磁盘。如果你想将PDF内容作为字节数组填充到表的'fileData'列中,请尝试'new ByteArrayOutputStream()。withStream {outputStream - > ...}' – ataylor 2011-05-16 23:43:05

+0

真的,我意识到它不仅仅是一点点冗余来将字节数据写入文件,然后读入该文件并获取字节以存储在表中。但是,如果我将文件创建/操作替换为文档中的def bytes =“”,我仍然会得到一个空白文件。 – 2011-05-17 01:40:03

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方法签名或...啊,谁需要样本呢?

希望这会帮助他人。

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

谢谢你们