itextpdf 实现html转pdf中中文及图片base64的解决方法

itextpdf 实现html转pdf中中文及图片base64的解决方法:

   1. 中文解决方案: 

        实现FontProvider接口:

package com.mumu.image2pdf;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontProvider;
import com.itextpdf.text.pdf.BaseFont;

public class MyFontProvider implements FontProvider {
	private BaseColor bc;
	private String fontname;
	private String encoding;
	private boolean embedded;
	private boolean cached;
	private float size;
	private int style;
	private BaseFont baseFont;

	public MyFontProvider() {
	}

	public BaseColor getBc() {
		return bc;
	}

	public void setBc(BaseColor bc) {
		this.bc = bc;
	}

	public String getFontname() {
		return fontname;
	}

	public void setFontname(String fontname) {
		this.fontname = fontname;
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public boolean isEmbedded() {
		return embedded;
	}

	public void setEmbedded(boolean embedded) {
		this.embedded = embedded;
	}

	public boolean isCached() {
		return cached;
	}

	public void setCached(boolean cached) {
		this.cached = cached;
	}

	public float getSize() {
		return size;
	}

	public void setSize(float size) {
		this.size = size;
	}

	public int getStyle() {
		return style;
	}

	public void setStyle(int style) {
		this.style = style;
	}

	public BaseFont getBaseFont() {
		return baseFont;
	}

	public void setBaseFont(BaseFont baseFont) {
		this.baseFont = baseFont;
	}

	public MyFontProvider(BaseColor bc, String fontname, String encoding, boolean embedded, boolean cached, float size,
			int style, BaseFont baseFont) {
		super();
		this.bc = bc;
		this.fontname = fontname;
		this.encoding = encoding;
		this.embedded = embedded;
		this.cached = cached;
		this.size = size;
		this.style = style;
		this.baseFont = baseFont;
	}

	@Override
	public Font getFont(String arg0, String arg1, boolean arg2, float arg3, int arg4, BaseColor arg5) {
		Font font = null;
		if (baseFont == null) {
			font = new Font();
		} else {
			font = new Font(baseFont);
		}
		font.setColor(arg5);
		font.setFamily(fontname);
		font.setSize(size);
		font.setStyle(arg4);
		return font;
	}

	@Override
	public boolean isRegistered(String arg0) {
		// TODO Auto-generated method stub
		return true;
	}
}

   2. 图片base64的dataurl显示问题解决:

     实现com.itextpdf.tool.xml.html.Image类

package com.mumu.image2pdf;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.NoCustomContextException;
import com.itextpdf.tool.xml.Tag;
import com.itextpdf.tool.xml.WorkerContext;
import com.itextpdf.tool.xml.exceptions.RuntimeWorkerException;
import com.itextpdf.tool.xml.html.HTML;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;

public class ImageTagProcessor extends com.itextpdf.tool.xml.html.Image {
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.itextpdf.tool.xml.TagProcessor#endElement(com.itextpdf.tool.xml.Tag, java.util.List, com.itextpdf.text.Document)
	 */
	@Override
	public List<Element> end(final WorkerContext ctx, final Tag tag, final List<Element> currentContent) {
	    final Map<String, String> attributes = tag.getAttributes();
	    String src = attributes.get(HTML.Attribute.SRC);
	    List<Element> elements = new ArrayList<Element>(1);
	    if (null != src && src.length() > 0) {
	        Image img = null;
	        if (src.startsWith("data:image/")) {
	            final String base64Data = src.substring(src.indexOf(",") + 1);
	            try {
	                img = Image.getInstance(Base64.decode(base64Data));
	            } catch (Exception e) {
	                throw new I18NIllegalArgumentException(e);
	            }
	            if (img != null) {
	                try {
	                    final HtmlPipelineContext htmlPipelineContext = getHtmlPipelineContext(ctx);
	                    elements.add(getCssAppliers().apply(new Chunk((com.itextpdf.text.Image) getCssAppliers().apply(img, tag, htmlPipelineContext), 0, 0, true), tag,
	                        htmlPipelineContext));
	                } catch (NoCustomContextException e) {
	                    throw new RuntimeWorkerException(e);
	                }
	            }
	        }

	        if (img == null) {
	            elements = super.end(ctx, tag, currentContent);
	        }
	    }
	    return elements;
	}
}

3. 转换方法:

public void html2pdf(String html, File file) throws I18NIllegalArgumentException {
		try {
			// step 1
			Document document = new Document();
			BaseFont bfChinese;

			bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
			MyFontProvider myFontProvider = new MyFontProvider(BaseColor.BLACK, "", "", false, false, 16, 1, bfChinese);

			// step 2
			PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
			// step 3
			document.open();
			
			final TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
	        tagProcessorFactory.removeProcessor(HTML.Tag.IMG);
	        tagProcessorFactory.addProcessor(new ImageTagProcessor(), HTML.Tag.IMG);
	        
	        
	        
	        final CssFilesImpl cssFiles = new CssFilesImpl();
	        cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS());
	        final StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles);
	        final HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(myFontProvider));
	        hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory);
	        final HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, writer));
	        final Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
	        
	        final XMLWorker worker = new XMLWorker(pipeline, true);
	        
	        final Charset charset = Charset.forName("UTF-8");
	        final XMLParser xmlParser = new XMLParser(true, worker, charset);
	        
	        ByteArrayInputStream bais = new ByteArrayInputStream(html.getBytes("UTF-8"));
	        xmlParser.parse(bais, charset);
			
			// step 5
			document.close();
			bais.close();
		} catch (Exception e) {
			throw new I18NIllegalArgumentException(e);
		}
	}

 

PS:  input框等的显示还没实现,待完善

   

转载于:https://my.oschina.net/u/1778261/blog/809757

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值