当前位置: 首页 > 面试题库 >

使用飞碟将图像渲染为内存中的PDF

甘学潞
2023-03-14
问题内容

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

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


问题答案:

上周我不得不这样做,因此希望我能够尽快回答您。

飞碟

最简单的方法是在使用飞碟进行渲染之前,将所需的图像添加为HTML模板中的标记。在飞碟内部,您将必须实现,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文件所在的文件夹,因为它将是用于飞碟解决媒体的根URL。您可以将其更改为正确的位置,可以从所需的任何位置(例如,属性)进行更改。

在您的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。这是一个非常整洁的库。



 类似资料:
  • 我正在使用飞碟将XHTML转换为PDF文档。我已经让代码只使用基本的HTML和内嵌CSS,然而,现在我正试图将一个图像作为某种头添加到PDF中。我想知道的是,是否有任何方法可以添加图像,通过读取图像文件作为Java图像对象,然后以某种方式将其添加到PDF(或XHTML——就像它得到一个虚拟的“url”,表示可以用于呈现PDF的图像对象)。有人做过这样的事吗? 提前感谢您提供的任何帮助!

  • 我试图从包含html代码的Java字符串生成pdf文档。我使用“Freemarker”作为模板引擎来生成html内容,然后使用“Flying Discer”将生成的html转换为pdf。我的问题是,图像不会在生成的pdf中呈现。关于我如何生成的具体细节如下: 生成的html(仅显示相关部分)为: 此代码作为部署在Tomcat上的War运行。作为tree命令(在WEB-INF中运行)的输出,图像在战

  • 问题内容: 有没有一种方法可以将html渲染为PNG图片?我知道画布是可能的,但我想呈现例如div之类的标准html元素。 问题答案: 我知道这是一个很老的问题,已经有了很多答案,但是我仍然花了几个小时来尝试做自己想做的事情: 给定一个html文件,从命令行生成具有 透明 背景的(png)图像 使用无头的Chrome(此响应的版本为74.0.3729.157),实际上很容易: 命令说明: 您可以从

  • 我正在使用飞碟从XHTML创建PNG图像文件。然后,我使用另一个工具将这些与一堆其他文本n图像一起收集到PDF中。 虽然我可以将PDF导出处理转换为iText,但这将是一项相当大的任务。。。。 我的问题是,当导出到PNG图像文件时,一些XHTML内容需要分页。我只需要在图像文件之间进行一个简单的“剪辑样式”分割就可以了。 下面是我用来将整个内容呈现到单个文件中的内容,效果很好。 然而,我的一些内容

  • 因此,在这个应用程序中,我们使用iText来填写PDF表单,并使用PDFBox将填写好的PDF加载到我们的系统中,并将其转换为图像。 问题是图像转换的时候。所有的信息都在那里,但是复选框...奇怪吗?复选框里面有一个奇怪的“空框”,而不是在PDF上设置的样式复选框“复选标记”。 它应该是怎样的: PDFBox版本2.0.11 iText版本为5.5.13 下面是进行转换的代码片段: 转换后,我也感

  • 我有一个jsp文件,我喜欢使用飞碟将其转换为PDF。以下是jsp文件: 以下是我用于将html解析为pdf的servlet代码: } } 我有个例外 有人能帮我吗?有没有可能从这种html页面创建pdf