简体   繁体   English

Grails将HttpInputStream渲染为pdf

[英]Grails render HttpInputStream as pdf

With the following code I am getting bad output like this: 使用以下代码,我得到的输出结果如下:

%PDF-1.4 % 4 0 obj <>stream x 3P0T 5T0P034 ɹ\\ \\N!\\ f f !)\\ !\\ \\ %@(Dɹ i . h @]z PF endstream endobj 6 0 obj <>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/MediaBox[0 0 612 792]/Rotate 90>> endobj 7 0 obj <>stream x } xU ;d"7! tor a H.! HDfLh 2 AEE E"8K A %Dhj :b D T Z U$ > pEѶ $ =k DA g E }[2^ ! 9' Zp _R / = Y W ߝ]7 P S#J*E 7) > f ͟9 3t g ?cɂ ! o y Z ; R* 渗R |J!2>>f : O 6z@̡h=. @ i5 ) Jѯ t "'ME ǁ D L h ^@ڳ KI" J k% P q4 ։3 W @: . 4 1n0i G EQ ƛ 9n [ m %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] / Rotate 90 >> endobj 7 0 obj <> streamx }xU ; d“7! tor a H。!HDfLh 2 AEEE”8K A %Dhj :b D T Z U$ > pEѶ $ =k DA g E } [2 ^ ! 9' Zp_R / = YWߝ] 7 PS#Ĵ* E7)> ?f͟93tgcɂOYZ;!R *渗[R |百灵2 >> F:O6z @ H = @ 3-15)Jѯt“'MEǁDLh ^ @ڳ ڳ KI“ J k% P q4 .3 W @: . 4 1n0i G EQ ƛ9n[米 qC CD- Hy- 4] ߡ t1ڠ zA ^G T R 4B * l @{E1Rf; 1 : [ v i " q Rw: i ~ bp .u O qC CD-Hy- 4] ߡ t1ڠ zA ^G T R 4B * l @ {E1Rf; 1 : [VI“QRW:ⅰ〜bp.uO

instead of pdf. 而不是PDF格式。 Here is the code: 这是代码:

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()
*/

How to get the actual pdf output in browser. 如何在浏览器中获得实际的pdf输出。

This assumes you are inside a controller, the return null at the end of the controller method ensure that Grails doesn't try and render anything. 这假设您在控制器内部,在控制器方法结束时返回null确保Grails不会尝试渲染任何内容。 Also, using Apache commons to copy the contents will prevent you from having to download the entire file into memory before sending it in the response. 此外,使用Apache commons复制内容将阻止您在将整个文件发送到内存之前将其发送到内存中。 This is modified from production code where I do something quite similar. 这是从生产代码修改的,我做了类似的事情。 Grails version(s) 1.3.7 and 2.0.4. 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

Are you trying the response inside a iframe? 您是否在iframe中尝试响应? If so, first try directly opening the output in a new window and see if it opens. 如果是这样,首先尝试在新窗口中直接打开输出并查看它是否打开。

If its opening try mapping your controller to something like abc.pdf so that the url you point to becomes /something/abc.pdf. 如果它的开放尝试将您的控制器映射到类似abc.pdf,以便您指向的URL变为/something/abc.pdf。

I resolved my problem doing the below code: 我解决了我的问题,做了以下代码:

Controller: 控制器:

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

Here, send the request to return stream like the first example, note that the contentType is binary 在这里,像第一个例子一样发送返回流的请求,注意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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM