解决iText+flying saucer+freemark导出pdf不支持base64的解决办法

新增一个类:

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;
	}


参考资源链接:[Java HTML转PDF图片显示问题解决方案](https://wenku.csdn.net/doc/4d0ddf4wb5?utm_source=wenku_answer2doc_content) 当你在Java项目中使用iTextFlyingSaucer库进行HTML到PDF的转换时,可能会遇到图片不显示的问题。这通常是因为转换过程中图片资源路径的问题。为了解决这个问题,你需要正确设置图片的资源目录,确保在渲染PDF时能够找到HTML中引用的图片。以下是一个使用iTextFlyingSaucer库将HTML转换为PDF并确保图片显示的Java代码示例:(代码示例,此处略)在这个示例中,我们创建了一个`HtmlToPdfConverter`类,其中包含了一个`convertHtmlToPdf`方法。这个方法首先使用`Document`和`PdfWriter`创建了一个PDF文档对象,然后利用`ITextRenderer`将HTML内容渲染到PDF中。关键步骤在于使用`setResourceDirectory`方法设置图片资源目录,这样iTextRenderer在渲染图片时就能找到正确的路径。确保将'path/to/image/folder'替换为实际存放HTML中图片的目录路径。这样,当你执行这个方法时,HTML文档中的图片就会正确显示在生成的PDF中。如果遇到图片不显示的问题,请首先检查HTML中的图片路径是否正确,以及图片资源目录是否设置正确。此外,理解iTextFlyingSaucer的API能够帮助你处理更复杂的文档转换问题,例如CSS样式、JavaScript等。为了深入学习和解决更多相关问题,你可以参考这份资源:《Java HTML转PDF图片显示问题解决方案》。这本书籍提供了实际的问题解决方案和代码示例,将帮助你更全面地掌握如何使用这些库来处理文档转换中的各种挑战。 参考资源链接:[Java HTML转PDF图片显示问题解决方案](https://wenku.csdn.net/doc/4d0ddf4wb5?utm_source=wenku_answer2doc_content)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值