gpt4 book ai didi

java - 使用 Flying Saucer 在内存中将图像渲染为 PDF

转载 作者:搜寻专家 更新时间:2023-10-30 19:49:59 24 4
gpt4 key购买 nike

我正在使用 Flying Saucer 将 XHTML 转换为 PDF 文档。我已经获得了仅使用基本 HTML 和内联 CSS 的代码,但是,现在我正尝试将图像作为一种标题添加到 PDF 中。我想知道的是,是否有任何方法可以通过将图像文件作为 Java Image 对象读取,然后以某种方式将其添加到 PDF(或 XHTML——就像它获得一个虚拟“url”一样)来添加图像表示可用于呈现 PDF 的图像对象)。有没有人做过这样的事情?

在此先感谢您提供的任何帮助!

最佳答案

上周我不得不这样做,所以希望我能马上给你答复。

飞碟

最简单的方法是在使用 Flying Saucer 渲染之前,在 HTML 模板中添加您想要的图像作为标记。在 Flying Saucer 中,您必须实现 ReplacedElementFactory这样您就可以在使用图像数据进行渲染之前替换任何标记。

/**
* Replaced element in order to replace elements like
* <tt>&lt;div class="media" data-src="image.png" /></tt> with the real
* media content.
*/
public class MediaReplacedElementFactory implements ReplacedElementFactory {
private final ReplacedElementFactory superFactory;

public MediaReplacedElementFactory(ReplacedElementFactory superFactory) {
this.superFactory = superFactory;
}

@Override
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox, UserAgentCallback userAgentCallback, int cssWidth, int cssHeight) {
Element element = blockBox.getElement();
if (element == null) {
return null;
}
String nodeName = element.getNodeName();
String className = element.getAttribute("class");
// Replace any <div class="media" data-src="image.png" /> with the
// binary data of `image.png` into the PDF.
if ("div".equals(nodeName) && "media".equals(className)) {
if (!element.hasAttribute("data-src")) {
throw new RuntimeException("An element with class `media` is missing a `data-src` attribute indicating the media file.");
}
InputStream input = null;
try {
input = new FileInputStream("/base/folder/" + element.getAttribute("data-src"));
final byte[] bytes = IOUtils.toByteArray(input);
final Image image = Image.getInstance(bytes);
final FSImage fsImage = new ITextFSImage(image);
if (fsImage != null) {
if ((cssWidth != -1) || (cssHeight != -1)) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
} catch (Exception e) {
throw new RuntimeException("There was a problem trying to read a template embedded graphic.", e);
} finally {
IOUtils.closeQuietly(input);
}
}
return this.superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight);
}

@Override
public void reset() {
this.superFactory.reset();
}

@Override
public void remove(Element e) {
this.superFactory.remove(e);
}

@Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
this.superFactory.setFormSubmissionListener(listener);
}
}

你会注意到我在这里硬编码了/base/folder这是 HTML 文件所在的文件夹,因为它将是 Flying Saucer 用于解析媒体的根 URL。您可以将其更改为正确的位置,来自您想要的任何位置(例如属性)。

HTML

在您的 HTML 标记中,您在某处指示了一个 <div class="media" data-src="somefile.png" />像这样:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My document</title>
<style type="text/css">
#logo { /* something if needed */ }
</style>
</head>
<body>
<!-- Header -->
<div id="logo" class="media" data-src="media/logo.png" style="width: 177px; height: 60px" />
...
</body>
</html>

渲染

最后您只需要指明您的 ReplacedElementFactory渲染时飞碟:

String content = loadHtml();
ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setReplacedElementFactory(new MediaReplacedElementFactory(renderer.getSharedContext().getReplacedElementFactory()));
renderer.setDocumentFromString(content.toString());
renderer.layout();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos);
// baos.toByteArray();

我一直在使用 Freemarker 从模板生成 HTML,然后将结果提供给 FlyingSaucer,并取得了巨大成功。这是一个非常简洁的库。

关于java - 使用 Flying Saucer 在内存中将图像渲染为 PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11477065/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com