Как установить базовый URL в Flying-Saucer при рендеринге HTML в PDF? - PullRequest
6 голосов
/ 06 декабря 2011

Я пытаюсь отобразить HTML-страницу в PDF с помощью Flying-Saucer. HTML создается в памяти и передается в средство визуализации как

renderer.setDocumentFromString(new String(htmlByteArray));

Проблема в том, что у меня <img src="images.jpg"/> в HTML, и он не отображается в окончательном HTML. Изображение находится в папке resources в упаковке.

Я попытался установить базовый URL следующим образом, но безуспешно:

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

1 Ответ

4 голосов
/ 31 декабря 2013

Theres действительно классный интерфейс в 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);
...