12

Flyingsaucer を使用して、生成された pdf ドキュメントを返すサーブレットを介して xhtml ドキュメントを pdf にレンダリングしています。xhtml ドキュメントには、別のサーブレットから要求された画像が含まれています。イメージ サーブレットは、適切なイメージを返す前に、誰がログインしているかを確認します。以下のコードは、画像がどのようにリクエストされるかを示しています。

<img height="140" width="140" src="http://localhost:8080/myapp/servlet/DisplayPic" />

私の問題は、画像のhttpリクエストがpdfレンダラーからのものであり、ログインしているユーザーからのものではないため、画像サーブレットは誰がログインしているかわからないため、目的の画像が返されないことです。

現在、以下のコードを使用して xhtml ドキュメントをレンダリングしています。

ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(xhtmlDocumentAsString);
renderer.layout();
os = response.getOutputStream();
renderer.createPDF(os);

画像サーブレットが要求されたときにユーザーのセッションを維持するか、その特定の xhtml 要素に使用する画像をレンダラーに提供する必要があります。後者は a を使用して実行できると思いますが、ReplacedElementFactory役立つサンプルコードを掘り出すことができませんでした。

4

1 に答える 1

24

私は今これを非常にうまく機能させています。これがコードです。

私のxhtmlドキュメントには次のものがあります:

<div class="profile_picture" style="display:block;width:140px;height:140px;" />

(ファクトリはブロックレベルの要素にのみ使用されるため、div代わりに要素を使用しています)img

以下を使用してドキュメントをレンダリングします。

ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setReplacedElementFactory(new ProfileImageReplacedElementFactory(renderer.getSharedContext().getReplacedElementFactory()));
renderer.setDocumentFromString(xhtmlDocumentAsString);
renderer.layout();
os = response.getOutputStream();
renderer.createPDF(os);

そして、私は以下のように自分のものを持ってReplacedElementFactoryいます:

public class ProfileImageReplacedElementFactory implements ReplacedElementFactory {

    private final ReplacedElementFactory superFactory;

    public ProfileImageReplacedElementFactory(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");
        if ("div".equals(nodeName) && className.contains("profile_picture")) {

            InputStream input = null;
            try {
                input = ...;
                byte[] bytes = IOUtils.toByteArray(input);
                Image image = Image.getInstance(bytes);
                FSImage fsImage = new ITextFSImage(image);

                if (fsImage != null) {
                    if ((cssWidth != -1) || (cssHeight != -1)) {
                        fsImage.scale(cssWidth, cssHeight);
                    }
                    return new ITextImageElement(fsImage);
                }
            } catch (IOException e) {
                getLogger().error(ExceptionUtils.getStackTrace(e));
            } catch (BadElementException e) {
                getLogger().error(ExceptionUtils.getStackTrace(e));
            } finally {
                IOUtils.closeQuietly(input);
            }
        }

        return superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight);
    }

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

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

    @Override
    public void setFormSubmissionListener(FormSubmissionListener listener) {
        superFactory.setFormSubmissionListener(listener);
    }
}
于 2012-04-26T15:04:55.637 に答える