2011-05-16 84 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') 

謝謝你們