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);
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With