gpc / rendering

Provides rendering of GSPs as PDFs, JPEGs, GIFs and PNGs
http://gpc.github.com/rendering
Apache License 2.0
31 stars 44 forks source link

Exception on using External CSS #33

Open Veeramanikandan1493 opened 7 years ago

Veeramanikandan1493 commented 7 years ago

Hi there, Is anyone successfully used external css like bootstrap.css on rendering pdf?. I am getting pdf that has only contents not styles with some exception thrown as shown below. If anyone got solution for this?

grails version 3.1.11 rendering:2.0.0-SNAPSHOT spring-test:4.2.1.RELEASE

java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:159)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at org.xhtmlrenderer.css.parser.Lexer.zzRefill(Lexer.java:1634)
    at org.xhtmlrenderer.css.parser.Lexer.yylex(Lexer.java:1865)
    at org.xhtmlrenderer.css.parser.CSSParser.next(CSSParser.java:1798)
    at org.xhtmlrenderer.css.parser.CSSParser.la(CSSParser.java:1810)
    at org.xhtmlrenderer.css.parser.CSSParser.stylesheet(CSSParser.java:159)
    at org.xhtmlrenderer.css.parser.CSSParser.parseStylesheet(CSSParser.java:89)
    at org.xhtmlrenderer.context.StylesheetFactoryImpl.parse(StylesheetFactoryImpl.java:78)
    at org.xhtmlrenderer.context.StylesheetFactoryImpl.parse(StylesheetFactoryImpl.java:95)
    at org.xhtmlrenderer.context.StylesheetFactoryImpl.getStylesheet(StylesheetFactoryImpl.java:174)
    at org.xhtmlrenderer.context.StyleReference.readAndParseAll(StyleReference.java:123)
    at org.xhtmlrenderer.context.StyleReference.setDocumentContext(StyleReference.java:107)
    at org.xhtmlrenderer.pdf.ITextRenderer.setDocument(ITextRenderer.java:175)
    at org.xhtmlrenderer.pdf.ITextRenderer.setDocument(ITextRenderer.java:142)
    at org.xhtmlrenderer.pdf.ITextRenderer$setDocument.call(Unknown Source)
    at grails.plugins.rendering.pdf.PdfRenderingService.doRender(PdfRenderingService.groovy:36)
    at sun.reflect.GeneratedMethodAccessor207.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1432)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182)
    at grails.plugins.rendering.RenderingService.render(RenderingService.groovy:43)
    at grails.plugins.rendering.RenderingService$render$1.callCurrent(Unknown Source)
    at grails.plugins.rendering.RenderingService.render(RenderingService.groovy:37)
    at grails.plugins.rendering.RenderingService.render(RenderingService.groovy:35)
    at grails.plugins.rendering.RenderingService$render$0.callCurrent(Unknown Source)
    at grails.plugins.rendering.RenderingService.render(RenderingService.groovy:65)
    at grails.plugins.rendering.RenderingService$render.call(Unknown Source)
    at com.test.SampleController$$EPwfKUe8.$tt__renderPdf(SampleController.groovy:110)
    at com.test.SampleController$$DPwfKUe8.$tt__renderPdf(Unknown Source)
    at com.test.SampleController.$tt__renderPdf(SampleController.groovy)
    at com.test.SampleController$_renderPdf_closure4$$EPwfKVAO.doCall(SampleController.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springsource.loaded.ri.ReloadedTypeInvoker$2.invoke(ReloadedTypeInvoker.java:133)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1461)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
    at groovy.lang.Closure.call(Closure.java:414)
    at com.test.SampleController$_renderPdf_closure4.call(SampleController.groovy)
    at groovy.lang.Closure.call(Closure.java:430)
    at com.test.SampleController$_renderPdf_closure4.call(SampleController.groovy)
    at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
    at com.test.SampleController$$EPwfKUe8.renderPdf(SampleController.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springsource.loaded.ri.ReloadedTypeInvoker$2.invoke(ReloadedTypeInvoker.java:133)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1461)
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:210)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:187)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:89)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
msaccone commented 7 years ago

Hi, I'm having exactly the same issue here. Setting grails.serverURL doesn't seem to solve it, as explained on "Link resources must be resolvable" section

msaccone commented 7 years ago

Hi, the problem is that resources aren't accessible from the process through http.

So I've finally "solved" this issue with a workaround....

  1. Create a gsp file in the current directory with the content of your css, called for example"_mycss.gsp" and then include it's content with from your gsp inside the head tag.
  2. Images must be encoded with 64 base using this tools 2.1 http://websemantics.co.uk/online_tools/image_to_data_uri_convertor/ 2.2. If image's size exceeds previous tool limit, use http://www.punypng.com/ to optimize and reduce it.

This works for me, I hope it does for you.

Veeramanikandan1493 commented 7 years ago

Hi, Thanks for the reply. Its worked.

  1. Create _css.gsp on same folder as _yourpdftemplate.gsp
  2. Add css on _yourpdftemplate.gsp's head section using <g:render template="css"/>
  3. If you going to use bootstrap css inside your _css.gsp, note below mentioned,
    • Comment the first occurred of @media print which is just above the glyphicons style.
    • Comment src: url(../fonts/glyphicons-halflings-regular.eot);
    • For glyphicons , add fonts folder which contains glyphicons fonts in the views directory.
msaccone commented 7 years ago

On monday in my office :)

Do u have any img referenced in your styles? The problem is the process can't access the resources through http, so they must be embeded too. Use base 64 to achieve this with the tools referenced on my answer

El 22/10/2016 04:06, "Veeramanikandan" notifications@github.com escribió:

Hi, Thanks for the reply.

  • I had created files and tried to include _css.gsp inside _mypdf.gsp.
  • But text still the same.

Can you give example for the answer you described?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/gpc/rendering/issues/33#issuecomment-255512055, or mute the thread https://github.com/notifications/unsubscribe-auth/ASUckiLHkgXs9OOfsJfgC4I1uix8wO6mks5q2bX4gaJpZM4J7c3c .

TRAT0R commented 7 years ago

I had a similar problem these days where after adding SSL to my server, the plugin just stopped reading resources (css, images), using either relative or absolute path. Also I configured the serverURL with HTTPS but works only in HTTP mode. I tested the above suggestion but could not include a custom font inside the views' folder.

@Veeramanikandan1493 How did you get to read the src property of your @font-face with glyphicons in the views' folder?

Veeramanikandan1493 commented 7 years ago

Hi @msaccone , I haven't tried any img reference on my application. I will let you know if there are any alternative methods.

Veeramanikandan1493 commented 7 years ago

Hi @TRAT0R , The default font-face styling contains src: url(../fonts/glyphicons-halflings-regular.eot);. You need to comment that. If you are using glyphicons you need to add glyphicons fonts folder and change urls in font-face style in relative path.

Veeramanikandan1493 commented 7 years ago

Hi @msaccone , I have tried image rendering using inlinepng. Its worked for me. On Controller: def grailsResourceLocator def logo = grailsResourceLocator.findResourceForURI("assets/images/logo.png").inputStream.bytes On rendering gsp: <rendering:inlinePng bytes="${logo}" class="some-class" style="width:15%; height: 60px"/>