使用flying saucer將html文件轉成PDF

使用flying saucer生成PDF文件之前,先要使用freemarker生成html文件,然後將html文件轉成pdf。生成html文件的東東網上一搜一大堆,大家找找就成。

當然“使用flying saucer將html文件轉成PDF“的東東網上也是一搜一大堆,所以我這篇主要不是講怎麼生成,而是記載一路走來碰到的各種奇葩問題。

 

還是上一下轉成pdf文件的方法吧,可能以後有用:

Java代碼 

/** 
 * 該方法用來將指定的word文件轉換成pdf文件(使用flying saucer技術) 
 * @param pdfPath:生成後的pdf所在目錄,包括目錄+pdf名稱+.+pdf 
 * @param htmlFilePath:需要進行轉換的html文件所在目錄,包括目錄+html名稱+.+html 
 * */  
public boolean createPDFByHtml(String pdfPath,String htmlFilePath){  
    boolean result = false;  
    //1、判斷給定的文件是否是html文件:是htm格式結尾,或者以html格式結尾  
    if(htmlFilePath.toUpperCase().endsWith(".HTM") ||   
            htmlFilePath.toUpperCase().endsWith(".HTML")){//兩種格式都是掃描文件格式  
        try {    
            OutputStream os = new FileOutputStream(pdfPath);    
            ITextRenderer renderer = new ITextRenderer();    
            renderer.setDocument(new File(htmlFilePath));   
              
            // 解決中文支持問題  
            ITextFontResolver fontResolver = renderer.getFontResolver();  
            fontResolver.addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
            fontResolver.addFont("C:/Windows/Fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
            fontResolver.addFont("C:/Windows/Fonts/simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
  
            renderer.layout();    
            renderer.createPDF(os);    
            os.close();    
            result = true;  
        } catch (Exception e) {    
            result = false;  
            e.printStackTrace();    
        }    
    }else{  
        result = false;  
    }  
    return  result ;  
}  

再說一下碰到的問題:

1、現象:不出現任何問題,pdf文件也不生成。使用debug跟蹤,跟蹤到ITextRenderer renderer = new ITextRenderer();時就進入到亂起八糟的東西里邊去了,F8直接結束debug依舊不報錯也不生成文件。

解決辦法:將catch中的Exception改成Throwable,再一執行,開始報錯了。

報錯:org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). java.io.IOException: Stream closed。

解決:通過將Exception改成Throwable纔出現錯誤應該就能猜到,是jar包出問題了。將系統中的iText的jar包改成iText-2.0.8.jar,據網上說flying saucer已經停止更新,可能在開發這個功能時用的是2.0.8的版本,而iText一直在更新且後面的版本不支持2.0.8中的這個功能。

 

2、報錯:java.lang.NoSuchMethodError: com.lowagie.text.pdf.BaseFont.getCharBBox(C)[I

解決:解決方法同1,替換jar包,只能換成2.0.8的,因爲其他版本的都沒有這個方法。

 

3、報錯:org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException: The entity "nbsp" was referenced, but not declared.

解決:這個是我做測試的時候報的錯,當時測試時html文件很簡單,只有基本標籤,如<html><head><body>等。解決辦法辦是爲html添加聲明,即:

將<html>替換成

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

替換成別的版本的聲明也行,我這個是因爲css要求這樣的聲明,否則樣式會出現問題。

 

4、報錯:org.xhtmlrenderer.util.XRRuntimeException: Can't load the XML resource (using TRaX transformer). org.xml.sax.SAXParseException: The element type "meta" must be terminated by the matching end-tag "</meta>".

解決:說實話,這個問題我並沒有碰到,因爲我所有的標籤都是結束了的,只是有些是使用簡寫,如<input />而不是<input></input>。之所以粘出來這個錯誤,因爲我無法重現那個錯誤而他們兩個報錯的原因是一致的,都是因爲標籤沒有結束。這個錯誤報的比較具體,有具體說到哪個標籤,我測試時報的錯比較迷糊,差不多就是說xml格式有問題,我查了下沒發現問題,後來把所有的簡寫改成一對一對的標籤纔沒有報錯。由此可見,flying saucer對xml格式要求很嚴格。

 

5、現象:生成的pdf只顯示數字和字母,不顯示中文。

解決:網上大部分的解決辦法都是說添加ITextFontResolver fontResolver = renderer.getFontResolver();fontResolver.addFont("C:/Windows/Fonts/SIMSUN.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);只有真正試過的人才知道,只加了這一句根本就沒用,即便是本地確實有這個文件或者換成別的所謂”宋體“的文件還是沒有用,還有一個關鍵點:body{font-family: SimSun;}

所以總結起來三個點:

a、在生成pdf的方法中添加代碼:ITextFontResolver fontResolver = renderer.getFontResolver();fontResolver.addFont("C:/Windows/Fonts/SIMSUN.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

b、確保C:/Windows/Fonts/SIMSUN.TTC這個文件確實存在(服務器上存在就成),若不存在從別的地方拷一個過來。

c、在模板文件頁面添加樣式:body{font-family: SimSun;}(SimSun只能是這樣子,不能改,改成別的就不認了)

存在的問題:中文的問題是解決了,但是html中字體樣式會丟失,如html文件中原本有加粗的字,轉成pdf之後不再有加粗的字。

 

6、現象:生成的pdf左側有邊框,右側沒有邊框

解決:我這裏用的是table佈局,table有定義寬度,每個td都有定義寬度,先將td的寬度調小,然後將table的寬度調小,可能要調小好幾次然後才能出右側邊框。

 

最後祝大家好運

PS:在這個過程中有碰到其他問題的可以給我留言,我弄個總得,以後別人碰到相同問題就不用再走冤枉路了,多謝多謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章