如何在 Flying-Saucer 中设置基本 url,同时将 HTML 渲染为 PDF?

发布于 2024-12-19 22:30:04 字数 606 浏览 1 评论 0原文

我正在尝试使用 Flying-Saucer 将 HTML 页面渲染为 PDF。 HTML 在内存中创建并传递给渲染器,因为

renderer.setDocumentFromString(new String(htmlByteArray));

问题是我在 HTML 中有 并且它没有在最终的渲染中呈现HTML。该图像位于包中的 resources 文件夹中。

我尝试使用以下内容设置基本网址,但没有成功:

ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setBaseURL("com/org/tools/designer/resources/");
System.out.println(renderer.getSharedContext().getBaseURL());
renderer.setDocumentFromString(new String(htmlByteArray));
renderer.layout();
renderer.createPDF(os);

I am trying to render a HTML page to PDF using Flying-Saucer. The HTML is created in memory and passed to the renderer as

renderer.setDocumentFromString(new String(htmlByteArray));

The issue is that I have <img src="images.jpg"/> in the HTML and it is not getting rendered in the final HTML. The image is located in the resources folder in the package.

I tried setting the base url with the following, but with no success:

ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setBaseURL("com/org/tools/designer/resources/");
System.out.println(renderer.getSharedContext().getBaseURL());
renderer.setDocumentFromString(new String(htmlByteArray));
renderer.layout();
renderer.createPDF(os);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

∞梦里开花 2024-12-26 22:30:04

FS 中有一个非常酷的接口,称为 UserAgentCallback,它允许您获取自己的所有资源。对于其他查看此内容的人,您可以相应地设置您的 url:

renderer.getSharedContext().getUserAgentCallback().setBaseURL("url_to_resources");

但是这里有一个特殊情况,您的 jar 文件中嵌入了需要特殊方式才能访问的资源。您可以实现自己的UserAgentCallback 这是我为您写的一个小例子。 (我没有测试这个,所以你可能需要稍微调试一下)。

此代码位扩展了 ITextUserAgent,这样您只需覆盖 getBinaryResource 方法,并将其余部分留给库。如果这不起作用,您可以考虑实现完整的UserAgentCallback

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextUserAgent;

public class PackageUserAgentCallback extends ITextUserAgent {
    private Class resourceClass;

    public PackageUserAgentCallback(ITextOutputDevice outputDevice, Class resourceClass) {
        super(outputDevice);
        this.resourceClass = resourceClass;
    }

    @Override
    public byte[] getBinaryResource(String uri) {
        try {
            InputStream in = resourceClass.getResourceAsStream(uri);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int numRead;
            byte [] buffer = new byte[256];
            while((numRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, numRead);
            }
            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

然后您可以将其设置为您的UserAgentCallback,这将通过您的PackageUserAgentCallback引导所有资源请求

ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setUserAgentCallback(
        new PackageUserAgentCallback(renderer.getOutputDevice(), Resources.class));
System.out.println(renderer.getSharedContext().getBaseURL());
renderer.setDocumentFromString(new String(htmlByteArray));

renderer.layout();
renderer.createPDF(os);

Theres a really cool interface in FS called UserAgentCallback that allows you to get all your own resources. For other people looking at this you can set your url accordingly:

renderer.getSharedContext().getUserAgentCallback().setBaseURL("url_to_resources");

However you have a special case here, you have resources embedded inside your jar file that need a special way to be accessed. You can implement your own UserAgentCallback Heres a little one I wrote up for you. (I did not test this so you may have to debug it a bit).

This code bit extends the ITextUserAgent that way you only have to overwrite the getBinaryResource method and leave the rest up to the library. If this isnt working out you can look into implementing a full on UserAgentCallback.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextUserAgent;

public class PackageUserAgentCallback extends ITextUserAgent {
    private Class resourceClass;

    public PackageUserAgentCallback(ITextOutputDevice outputDevice, Class resourceClass) {
        super(outputDevice);
        this.resourceClass = resourceClass;
    }

    @Override
    public byte[] getBinaryResource(String uri) {
        try {
            InputStream in = resourceClass.getResourceAsStream(uri);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int numRead;
            byte [] buffer = new byte[256];
            while((numRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, numRead);
            }
            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

Then you can set this to your UserAgentCallback, this would direct all resource requests through your PackageUserAgentCallback

ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setUserAgentCallback(
        new PackageUserAgentCallback(renderer.getOutputDevice(), Resources.class));
System.out.println(renderer.getSharedContext().getBaseURL());
renderer.setDocumentFromString(new String(htmlByteArray));

renderer.layout();
renderer.createPDF(os);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文