Grails将HttpInputStream渲染为pdf

时间:2014-03-12 15:26:37

标签: java java-ee pdf grails inputstream

使用以下代码,我得到的输出结果不好:

%PDF-1.4% 40 obj<>streamx 3P0T 5T0P034 ɹ\ \ N!\ f f!)\ !\ \ %@( Dɹɹi . h @]z PF ndndstreamendobj 6 0 obj<> / ProcSet [/ PDF / Text / ImageB / ImageC / ImageI]>> / MediaBox [0 0 612 792] /旋转90>> endobj 7 0 obj<>流x }xU ; d“7! tor a H。!HDfLh 2 AEEE” 8K A %Dhj :b D T Z U$ > pEѶ $ =k DA g ë} [2 ^!9'Zp_R / = YWߝ] 7 PS#Ĵ* E7) >?!f͟93tgcɂOYZ !; R *渗 - [R |百灵2 - ;> F:O6z @ H = @ I5)Jѯt“'ME。 ǁ D L h ^ @ڳ ڳ KI“ J k% P q4 .3 W @: 。 41n0i G EQ ƛ 9n [ mqC CD-Hy- 4] ߡ t1ڠ zA ^G T R 4B * 升@ {E1Rf; 1:[VI“QRW:I〜BP。 UO

而不是pdf。这是代码:

URL url = new URL(urlStr)
URLConnection connection = url.openConnection();
response.contentType = 'application/pdf'
response.setHeader("Content-Disposition","Attachment; filename=gdoc.pdf")
def bytes = connection.getInputStream().getBytes()
response.getOutputStream().write(bytes)
response.outputStream.flush()
response.outputStream.close()

/*
  //writing to a pdf file works perfectly
  def outputStream =  new FileOutputStream(new File("gdoc/abc.pdf"));
  outputStream.write(bytes)
  outputStream.close()
*/

如何在浏览器中获得实际的pdf输出。

3 个答案:

答案 0 :(得分:1)

这假设您在控制器内部,控制器方法结束时返回null确保Grails不会尝试渲染任何内容。此外,使用Apache commons复制内容将阻止您在将整个文件发送到内存之前将其发送到内存中。这是从生产代码修改的,我做了类似的事情。 Grails版本1.3.7和2.0.4。

URL url = new URL(urlStr)

response.setContentType("application/pdf")
response.setHeader("Content-disposition", "attachment;filename=gdoc.pdf")

// this will actually buffer/stream the file in 8k chunks instead of reading the entire file into memory.
org.apache.commons.io.IOUtils.copy(url.openStream(), response.outputStream)
response.outputStream.flush()
response.outputStream.close()

// make sure Grails doesn't render anything for the request.
return null

答案 1 :(得分:1)

您是否在iframe中尝试响应?如果是这样,首先尝试在新窗口中直接打开输出,看看它是否打开。

如果它的开头尝试将你的控制器映射到像abc.pdf这样的东西,那么你指向的url就变成了/something/abc.pdf。

答案 2 :(得分:0)

我通过以下代码解决了我的问题:

  

控制器:

    def bytes = SendHttpService.executeGetBinary("http://app.com",  
                                                  "/pdf/", params)
    response.setHeader("Expires", "0");
    response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
    response.setHeader("Pragma", "public");
    response.setHeader("Content-Disposition", "inline; filename=\"relatorioGerencial.pdf\"");
    response.setContentType("application/pdf");
    response.setContentLength(bytes.length);
    ServletOutputStream ouputStream = response.getOutputStream();
    ouputStream.write(bytes,0,bytes.length);
    ouputStream.flush();
    ouputStream.close();
  

这里,将请求发送到返回流,如第一个示例,请注意contentType是二进制

    def executePostBinary = { String httpUrl, String dataBody, String path, query = null, method = Method.POST->

    def http = new HTTPBuilder()
    try{
        http.request( httpUrl , method , ContentType.BINARY ) { req ->

            uri.path = path
            uri.query = trataQuery(query)
            headers.'User-Agent' = "Mozilla/5.0 Firefox/3.0.4"
            headers.Accept = ContentType.BINARY
            if(method==groovyx.net.http.Method.POST && dataBody!=null){
                body = dataBody
            }

            response.success = { resp, inputStream  ->
                inputStream.bytes

            }

            response.'404' = {
                'Not found'
            }
        }
    }catch(HttpResponseException e){
        println "Error "+e
        println "Error Code "+e.statusCode
        return false
    }
}