flyingsaucerproject / flyingsaucer

XML/XHTML and CSS 2.1 renderer in pure Java
Other
1.96k stars 549 forks source link

org.xhtmlrenderer.pdf.ITextRenderer.setDocumentFromString - missing 'baseUrl' parameter #291

Closed gerpres closed 4 months ago

gerpres commented 4 months ago

to check #276 I tried to upgrade to 9.6.1 (from 9.1.22) causing my code to fail. we are trying to generate pdf from a html that's generated in memory.

we then used to call renderer.setDocument(Document doc, String url)

that method seems to be private now. all alternatives don't allow to pass a baseUrl parameter, causing relative URLs (CSS) to fail.

is there any other alternative?

asolntsev commented 4 months ago

@gerpres it seems I made too much refactoring:) I thought nobody uses this method anymore :)

I can make it public again in next version.

gerpres commented 4 months ago

thx. I don't insist on the same method. just a way to specify the baseUrl. to get rid of having to convert it to w3c.dom manually would be nice.

asolntsev commented 4 months ago

@gerpres In FS 9.6.1, I added factory method ITextRenderer.fromString.

Instead of calling constrctor+setDocumentFromString sequentially:

        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocumentFromString(content);

now you can call a single method fromString:

  ITextRenderer renderer  = fromString(content);

Now (in FS 9.7.0) I also added factory method fromString with the second parameter baseUrl. Hope it helps to shorten your code.

gerpres commented 4 months ago

thx for your quick resonses/fixes.

additionally, before calling setDocument() we also use renderer.getSharedContext().setUserAgentCallback() to add a custom UserAgentImplementation that overrides openConnection, getImageResource, getCSSResource for some purposes.

and also renderer.getSharedContext.setReplacedElementFactory() to support inlined base64 images.

since the callbacks need to be set before calling setDocument(), i'm afraid the factory approach will not work

asolntsev commented 3 months ago

@gerpres Thank you for sharing how you are using FS. Yes, the simple factory approach doesn't work for you, but method setDocumentFromString(String content, @Nullable String baseUrl) was also made public again.

P.S. But I am still thinking about some advanced factory approach where you can set all these "user agent", "replaced element factory" etc.

NB! What exactly are you customizing in openConnection, getImageResource, getCSSResource - isn't this logic useful for others too? Shouldn't we include this functionality in FS? The same question for base64 images - don't we want to support them in FS out-of-the-box?

gerpres commented 3 months ago

getImageResource: in case of SVG images, we redirect to the PNG representation, that we also host. getCSSResource: the CSS is provided via a servlet. add some control-parameters to the URL (UI theme,...) openResource: https-handling. trust any certificates. share current session/cookies only with 'local' URL base64-images: we do something like this: https://www.tothenew.com/blog/using-data-urls-for-embedding-images-in-flying-saucer-generated-pdfs/