用itext把html转成pdf,带图片

很久以前使用itext转换html到pdf过,但当时没记录,最近又有这种需求,一直没想起来,现在做好了记录一下

下面是伪代码:

依赖jar包及版本:

                <groupId>com.lowagie</groupId>  
        <artifactId>itext</artifactId>  

        <version>2.0.8</version>

 

               <groupId>org.xhtmlrenderer</groupId>  
       <artifactId>core-renderer</artifactId>  

       <version>R8</version>  

注意事项:

1.html标签必须成对,有对应的结束标签,比如<meta/>或<meta></meta>

2.在样式表中第一行加入@page{size:200mm 300mm;} 可以设置PDF宽高

3.该版本不支持CSS3,所以页面中如果有CSS3的样式写法,可能需要修改成CSS2

4.html中必须设置中文字体样式,否则中文无法正常显示,比如:<body style = 'font-family:SimSun;'>,且字体样式必须与下面代码中设置的一致,比如使用了C:/Windows/Fonts/simsun.ttc,则此处必须使用SimSun(区分大小写)

-Html2Pdf.java-----------------------------------------------------------------------------------------------------------------------

                        OutputStream os = new FileOutputStream("PDF文件输出全路径");  
ITextRenderer renderer = new ITextRenderer();  
// 图片base64支持,把图片转换为itext自己的图片对象
if(hasImage) {// 如果携带图片则加上以下代码,将图片标签转换为Itext自己的图片对象
renderer.getSharedContext().setReplacedElementFactory(new Base64ImgReplacedElementFactory());  
renderer.getSharedContext().getTextRenderer().setSmoothingThreshold(0);  
}

renderer.setDocumentFromString(html);
// 解决中文支持问题  
ITextFontResolver fontResolver = renderer.getFontResolver();  
// 字体设置,字体文件路径比如可以为C:/Windows/Fonts/simsun.ttc,也可以拷贝到其他目录
fontResolver.addFont("字体文件路径", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
// renderer.getSharedContext().setBaseURL("file:/D:/z/temp/");  // 如果img标签中src是http或绝对地址可以不要本行代码,另外对于linux系统中写法暂不确认应该是不需要file:/前缀
renderer.layout();  
renderer.createPDF(os);  

os.close();

Base64ImgReplacedElementFactory.java:----------------------------------------------------------------------------------

 


import java.io.IOException;


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;
import com.lowagie.text.pdf.codec.Base64;
/**
 * 图片base64支持,把图片转换为itext自己的图片对象
 * @author Administrator
 *
 */
public class Base64ImgReplacedElementFactory implements ReplacedElementFactory {


    /**
     * 实现createReplacedElement 替换html中的Img标签
     * 
     * @param c 上下文
     * @param box 盒子
     * @param uac 回调
     * @param cssWidth css宽
     * @param cssHeight css高
     * @return ReplacedElement
     */
    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;
    }


    /**
     * 编解码base64并生成itext图像    
     */
    protected FSImage buildImage(String srcAttr, UserAgentCallback uac) throws IOException,
            BadElementException {
        FSImage fiImg=null;
        if (srcAttr.toLowerCase().startsWith("data:image/")) {
            String base64Code= srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length(),
                    srcAttr.length());
            // 解码
            byte[] decodedBytes = Base64.decode(base64Code);


            fiImg= new ITextFSImage(Image.getInstance(decodedBytes));
        } else {
            fiImg= uac.getImageResource(srcAttr).getImage();
        }
        return fiImg;
    }


    public void reset() {}

    @Override
    public void remove(Element arg0) {}

    @Override
    public void setFormSubmissionListener(FormSubmissionListener arg0) {}

}

----------------------------------------------------------------------------------

展开阅读全文

没有更多推荐了,返回首页