Play Framework:PDF'通过Job使用highcharts JS库的模板

dig*_*nie 6 java pdf-generation highcharts playframework

这是我之前发布的帖子的扩展.

总结一下发生了什么:

  • 我正在使用一个每小时执行一次的Job,它将生成一个PDF作为电子邮件中的附件发送
  • 作业没有太大作用,但直接调用控制器生成PDF并发送电子邮件.我打电话给控制器来完成工作,因为我正在使用PDF模块(当前)需要HTTP请求作为其PDF处理的一部分.以下是我通过Job调用控制器的方法:

    WS.url( "我的/ URL /是/点/到/的/控制器")得到().

  • 我之前关于包含高图JS图表的PDF模板的问题在于它生成了图表客户端,这对于PDF生成来说已经太晚了,因此我的PDF生成减去了图表.为了解决这个问题,我现在使用highcharts-serverside-export来生成图表服务器端

如果我使用上面的相同类并在浏览器中呈现模板(即直接通过控制器并忽略Job),则会在服务器端创建图表,并在浏览器中正确呈现视图.

我通过调用另一个控制器来生成模板中的图表,如下所示:

<img src="@{ChartGenerator.go()}">
Run Code Online (Sandbox Code Playgroud)

ChartGenerator控制器基本上按照highcharts-serverside-export文档构建图表服务器端,并调用Play的renderBinary方法.

正如我所说,模板在浏览器中使用服务器端生成的图表呈现正常.但是,当通过每小时执行一次的Job时,ChartGenerator.go()调用似乎不起作用.控制台吐出这个:

INFO  ~ /chartgenerator/go is not a URL; may be relative.
Run Code Online (Sandbox Code Playgroud)

有没有人有任何想法如何解决这个问题?我已经证明它可以减去工作,现在需要弄清楚为什么当通过工作时,它似乎不起作用.

编辑:根据Pere的建议,我的模板现在通过执行此操作调用ChartGenerator类(请注意double @'s):

 <img src="@@{ChartGenerator.go()}">
Run Code Online (Sandbox Code Playgroud)

我认为这让我更进一步,现在这在日志中吐出来:

Error during job execution (fun.EmailJob)
Execution exception (In /fun/EmailJob.java around line 19)
RuntimeException occured : java.util.concurrent.ExecutionException: java.util.concurrent.TimeoutException: No response received after 60000
...
09:23:54,687 WARN  ~ bad URL given: http://<full url>/chartgenerator/go
java.net.SocketTimeoutException: Read timed out
Run Code Online (Sandbox Code Playgroud)

如果我在浏览器中点击http:// <full url>/chartgenerator/go的URL,则会在浏览器中正确呈现highcharts png文件.正如预期的那样,即使在这个double @ change之后,如果我在浏览器中渲染模板(没有pdf'ing),模板也会正确地呈现服务器端生成的图表.

编辑#2:我遇到这些问题似乎是通过从模板中调用控制器来渲染图像(二进制),我想知道是否可以将File对象(包含图像)作为参数传递给模板的render(...)方法.例如,假设呈现模板的控制器执行此操作:

File image = ... // PNG chart as built by the highcharts-serverside-export library
...
File emailAttachment = new File("attachment.pdf");
PDF.writePDF(emailAttachment, "myTemplate.html", image); // This calls the PDF module to render the PDF from the given template and write it to the attachment.pdf File object
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以直接在模板中呈现该图像而无需通过@@ {...}方式?

我尝试将$ {image}放在模板中,但这只是在屏幕上呈现attachment.pdf(有点期待).

编辑#3:这是ChartGenerator类的样子:

public final class ChartGenerator extends Controller {
    public static void go() throws Exception {
        ChartOptions options = SamplesFactory.getSingleton().createColumnBasic();
        HighchartsExporter pngExporter = ExportType.png.createExporter();
        File chart = new File("column-basic.png");
        pngExporter.export(options, null, chart);
        response.setContentTypeIfNotSet("image/png");
        renderBinary(chart);
    }
}
Run Code Online (Sandbox Code Playgroud)

我目前只是生成一个示例图表服务器端来证明它可以是pdf'ed.样本图表生成按照highcharts-serverside-export文档完成.

编辑#4:我还尝试向控制器添加一个动作方法以允许在浏览器中进行pdf,并且服务器端生成的高图也不会出现在pdf中,并且仍然会出现前面提到的异常.所以我可以排除它是Job to Controller工作流程的问题.(当然渲染模板没有pdf'ing仍然可以正常工作)

编辑#5:为了帮助缩小问题的可能原因,我决定忽略highcharts(以及highcharts-serverside-export库)并使用简单的服务器端图表库jfreechart.同样,我可以在没有pdf的情况下渲染模板,但是一旦我尝试pdf包含图表的模板(通过前面提到的@@调用呈现),它最终会因同样的原因失败(即给出错误的URL, java.net.SocketTimeoutException:读取超时).

dig*_*nie 1

好吧,我已经成功让它发挥作用了(终于)。这一切都源于我处于 DEV 模式这一事实(显然是因为我仍在开发这一功能)。但在 DEV 模式下,我(默认情况下)只能访问一个线程。所以我所要做的就是取消 application.conf 中执行池的注​​释:

play.pool=3
Run Code Online (Sandbox Code Playgroud)

然后我的 highchart 开始在服务器上渲染,然后作为 PDF 的一部分插入。附加线程用于渲染图表的请求。对于这种情况,一个线程是不够的,因此对 URL 的调用来渲染图像二进制文件挂起。