1. 程式人生 > >用itext把html轉成pdf,帶圖片

用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) {}

}

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