2

这是我目前的工作流程:

  1. 从数据库加载 POJO。
  2. 将它们传递给 Velocity,在内存中呈现 HTML 模板。
  3. 然后使用 Flying Saucer 和 iText 将输出的 HTML 渲染为 PDF。

当我尝试解析图像等相对 URL 时会出现问题。由于我的文档存在于内存中,它根本不知道如何解析图像或样式表。如何将文档设置为内存中的 String 对象,同时仍将其传递给目录以从中加载资源?

String velocityOutput = VelocityEngineUtils.mergeTemplateIntoString(...);

ByteArrayOutputStream output = new ByteArrayOutputStream(...);

ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(velocityOutput);
renderer.layout();
renderer.createPDF(output);

我需要在内存中做所有事情,因为我只是生成要通过电子邮件发送给客户的报告。生成为 PDF 时,如何<img src="..."/>在我的 HTML 模板中解析相对 URL?

4

2 回答 2

2

您应该实现UserAgentCallback接口并将其设置为renderer.getSharedContext().setUserAgentCallback(myUserAgentCallback);

从javadoc:

在这种情况下,用户代理负责检索外部资源。

要了解如何创建自己的 UAC,最好查看库附带的一些实现,例如 {@link org.xhtmlrenderer.swing.NaiveUserAgent}。

于 2012-03-16T18:16:14.510 回答
1

最后我只是简单地将我的文档加载到一个 JavaDocument实例中,然后在一次调用中将它与资源目录一起发送到 Flying Saucer:

Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
                .parse(new ByteArrayInputStream(templateOutput.getBytes("UTF-8")));

ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(document, templateResourceDirectory);
    renderer.layout();

OutputStream result = new ByteArrayOutputStream();

renderer.createPDF(result);

需要特别注意的一件事是,Flying Saucer 需要基于文件的 URI 以 为前缀file://,并且它需要在文件路径末尾加上斜杠才能正常工作:

/var/www/cache         # FAIL
file:///var/www/cache  # ALSO FAIL
file:///var/www/cache/ # WIN
于 2012-03-16T18:58:55.210 回答