新增一个类:
package org.k12py.common.plug;
import java.io.IOException;
import org.bouncycastle.util.encoders.Base64;
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.BadElementException;
import com.lowagie.text.Image;
/**
*
* 项目名称:k12py_dev <br>
* 类名称:B64ImgReplacedElementFactory <br>
* 类描述:TODO(解决iText+flying saucer+freemark导出pdf不支持base64) <br>
* 创建人:<br>
* 创建时间:2016年11月1日 下午7:11:49 <br>
*
* @version V1.0
*/
public class B64ImgReplacedElementFactory implements ReplacedElementFactory {
/*
*
* <p>Title: createReplacedElement</p>
* <p>Description: </p>
* <p>sql: </p>
*
* @author 2016年11月1日 下午7:05:55
*
* @param c 上下文
* @param box 盒子
* @param uac 回调
* @param cssWidth css宽
* @param cssHeight css高
* @return
* @see org.xhtmlrenderer.extend.ReplacedElementFactory#createReplacedElement(org.xhtmlrenderer.layout.LayoutContext, org.xhtmlrenderer.render.BlockBox, org.xhtmlrenderer.extend.UserAgentCallback, int, int)
*/
@Override
public ReplacedElement createReplacedElement(LayoutContext c, BlockBox box, UserAgentCallback uac, int cssWidth,
int cssHeight) {
Element e = box.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
// 找到img标签
if (nodeName.equals("img")) {
String attribute = e.getAttribute("src");
FSImage fsImage;
try { // 生成itext图像
fsImage = buildImage(attribute, uac);
} catch (BadElementException e1) {
fsImage = null;
} catch (IOException e1) {
fsImage = null;
}
if (fsImage != null) { // 对图像进行缩放
if (cssWidth != -1 || cssHeight != -1) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
}
return null;
}
/**
*
* TODO(将base64编码解码并生成itext图像)
* @author 2016年11月1日 下午7:08:57
* @param srcAttr 属性
* @param uac 回调
* @return
* @throws IOException
* @throws BadElementException
*/
protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException, BadElementException {
FSImage fsImage;
if (srcAttr.startsWith("data:image/")) {
String b64encoded = srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length(), srcAttr.length()); // 解码
byte[] decodedBytes = Base64.decode(b64encoded);
fsImage = new ITextFSImage(Image.getInstance(decodedBytes));
} else {
fsImage = uac.getImageResource(srcAttr).getImage();
}
return fsImage;
}
@Override
public void remove(Element arg0) {
// TODO 自动生成的方法存根
}
@Override
public void reset() {
// TODO 自动生成的方法存根
}
@Override
public void setFormSubmissionListener(FormSubmissionListener arg0) {
// TODO 自动生成的方法存根
}
}
生成pdf时:
/**
*
* TODO(生成PDF到输出到流中)
*
* @author 2016年5月16日 下午2:54:46
* @param classpath
* @param pyFinalistNoticeVOs
* @param response
* @return
* @throws TemplateNotFoundException
* @throws MalformedTemplateNameException
* @throws ParseException
* @throws IOException
* @throws TemplateException
* @throws DocumentException
*/
public static OutputStream generateToServletOutputStream(String classpath, String ftlName, Object data,
HttpServletResponse response) throws TemplateNotFoundException, MalformedTemplateNameException,
ParseException, IOException, TemplateException, DocumentException {
Map<Object, Object> o = new HashMap<Object, Object>();
o.put("d", data);
String html = PdfHelper.getPdfContent(classpath + FTL_PATH, ftlName, o);
OutputStream out = null;
ITextRenderer render = null;
out = response.getOutputStream();
render = PdfHelper.getRender(classpath + FTL_FONT_PATH);
render.setDocumentFromString(html);
// ftl中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
render.getSharedContext().setBaseURL("file:" + classpath + FTL_IMAGES_PATH);
// 支持BASE64图片
render.getSharedContext().setReplacedElementFactory(new B64ImgReplacedElementFactory());
render.layout();
render.createPDF(out);
render.finishPDF();
render = null;
return out;
}