我有一个项目需要生成 PDF 文件。在此 PDF 中,我必须插入正文以及四到五张大图像(大约 800px*1000px)。为了使其更加灵活,我选择将 FreeMarker 与 XHTMLRenderer( Flying Saucer )结合使用。
我现在面临两个选择:
- 创建图像并将它们作为临时文件保存到磁盘。然后使用 FreeMarker 处理一个
.xhtml
模板(将其保存到磁盘)并将处理后的.xhtml
文件 URL 传递给 XHTMLRenderer 以生成 PDF。所有这些创建的文件(PDF 除外)都将使用File.createTempFile
创建。这将允许 FreeMarker 从磁盘中拾取图像(就好像它们是在 XHTML 中链接的图像) - 处理
.xhtml
模板并将其保存在内存中。将图像作为 base64 编码的数据 url 传递给模板。这将消除保存任何临时文件的需要,因为 FreeMarker 的输出可以直接传递给 XHTMLRenderer。
Base64 编码的图像 Url 示例(一个小文件夹图标):
<img src="data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub/
/ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExK
cppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7" />
我的主要问题是哪种技术更好?创建大量临时文件不好吗(它会带来很多开销)吗?我可能会在创建如此大的 base64 编码字符串时耗尽内存吗?
最佳答案
我发现自己最近也在问同样的问题。经过一些基准测试后,事实证明数据 URI 方法是最好的选择。
存储一堆 Base64 编码的图像可能很昂贵。但是创建临时文件、流式传输图像数据,然后等待 XHTMLRenderer 在清理临时文件之前命中该临时文件 4 次的开销也很繁重。
在我的实验中,Base64 图像被证明是一种更好的方法。话虽如此,我不确定它在多大程度上适用于较大的图像。就我而言,我使用 32x32 图标、80x80 Logo 、400x240 条形图和一个 600x400 图形进行测试。除了 600x400 图形之外,所有内容的开销差异都非常显着,在那里它可以忽略不计。
(Joop Eggen 的旁注 - 在我的例子中,PDF 生成时间紧迫。用户单击 PDF 按钮并希望立即开始下载。)
关于java - 内联图像与临时文件(Java XHTML->PDF 生成),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8844043/