I am working in html to pdf conversion using flying saucer(itextrenderer)...I have to render image..I have rendered the image which was in my local storage(it works fine)..I have to do the same thing with external image..
Here is my code snippet for html to pdf image renderer...
{
try {
String url = new File(inputHtmlPath).toURI().toURL().toString();
System.out.println("URL: " + url);
OutputStream out = new FileOutputStream(outputPdfPath);
File signUpTemplate = new File("C:/Users/SFLTP022/Desktop/task/index1.html");
String content=FileUtils.readFileToString(signUpTemplate);
//Flying Saucer part
ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setReplacedElementFactory(new MediaReplacedElementFactory(renderer.getSharedContext().getReplacedElementFactory()));
renderer.setDocumentFromString(content.toString());
renderer.layout();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos);
//ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
renderer.layout();
renderer.createPDF(out);
out.close();
}
Here is my default class to render html image,in which i have to load external image
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import org.apache.commons.io.IOUtils;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.FSImage;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.extend.ReplacedElementFactory;
import org.xhtmlrenderer.extend.UserAgentCallback;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.pdf.ITextFSImage;
import org.xhtmlrenderer.pdf.ITextImageElement;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.simple.extend.FormSubmissionListener;
import com.lowagie.text.Image;
public class MediaReplacedElementFactory implements ReplacedElementFactory {
private final ReplacedElementFactory superFactory;
public MediaReplacedElementFactory(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");
// Replace any <div class="media" data-src="image.png" /> with the
// binary data of `image.png` into the PDF.
if ("div".equals(nodeName) && "media".equals(className)) {
if (!element.hasAttribute("data-src")) {
throw new RuntimeException("An element with class `media` is missing a `data-src` attribute indicating the media file.");
}
InputStream input = null;
try {
input = new FileInputStream("https://cdn.zetran.com/testasset/images/banner/zetran/banner-parts/base/png/" + element.getAttribute("data-src"));
final byte[] bytes = IOUtils.toByteArray(input);
final Image image = Image.getInstance(bytes);
final FSImage fsImage = new ITextFSImage(image);
if (fsImage != null) {
if ((cssWidth != -1) || (cssHeight != -1)) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
} catch (Exception e) {
throw new RuntimeException("There was a problem trying to read a template embedded graphic.", e);
} finally {
IOUtils.closeQuietly(input);
}
}
return this.superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight);
}
@Override
public void reset() {
this.superFactory.reset();
}
public void remove(Element e) {
this.superFactory.remove(e);
}
@Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
// TODO Auto-generated method stub
}
}
When i tried this by loading local image it works fine,as shown below
input = new FileInputStream("C:\Users\Public\Pictures\Sample Pictures\" + element.getAttribute("data-src"));
My html part(local storage image) looks like
<div id="logo" class="media" data-src="Desert.jpg" style="width: 177px; height: 60px" />
My html part(External storage image) looks like
<div id="logo" class="media" data-src="base.png" style="width: 177px; height: 60px" />
The error message is
java.lang.RuntimeException: There was a problem trying to read a template embedded graphic.
at com.boot.MediaReplacedElementFactory.createReplacedElement(MediaReplacedElementFactory.java:56)
at org.xhtmlrenderer.render.BlockBox.calcDimensions(BlockBox.java:716)
at org.xhtmlrenderer.render.BlockBox.calcDimensions(BlockBox.java:666)
at org.xhtmlrenderer.render.BlockBox.collapseBottomMargin(BlockBox.java:1205)
at org.xhtmlrenderer.render.BlockBox.collapseBottomMargin(BlockBox.java:1228)
at org.xhtmlrenderer.render.BlockBox.collapseMargins(BlockBox.java:1126)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:811)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:776)
at org.xhtmlrenderer.layout.BlockBoxing.layoutBlockChild0(BlockBoxing.java:321)
at org.xhtmlrenderer.layout.BlockBoxing.layoutBlockChild(BlockBoxing.java:299)
at org.xhtmlrenderer.layout.BlockBoxing.layoutContent(BlockBoxing.java:90)
at org.xhtmlrenderer.render.BlockBox.layoutChildren(BlockBox.java:967)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:847)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:776)
at org.xhtmlrenderer.pdf.ITextRenderer.layout(ITextRenderer.java:229)
at com.boot.App6.generatePDF(App6.java:67)
at com.boot.App6.main(App6.java:27)
Caused by: java.io.FileNotFoundException: https:\cdn.zetran.com\testasset\images\banner\zetran\banner-parts\base\png\base.png (The filename, directory name, or volume label syntax is incorrect)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at com.boot.MediaReplacedElementFactory.createReplacedElement(MediaReplacedElementFactory.java:45)