1. 程式人生 > >itext xmlworker轉換html生成pdf檔案

itext xmlworker轉換html生成pdf檔案

工作需要,把一些表格以pdf格式輸出以供列印。查到itext是java的開源生成pdf的工具包,看了使用後感覺好複雜,竟然要把表格用itext語法重新繪製到pdf文件中。再查直接轉換html到pdf的工具,發現有flying-saucer,看了下感覺更新不是很及時,又看了Ireport,感覺是從資料庫匯出多項資料成報表的,和我要轉換html table的思路不一致。後來查到itext有個獨立的xmlworker就做這件事情,想著itext分屬出來的應該和itext的整合比較好,就選了這個。

itextpdf-5.3.5,xmlworker5.4.0,以及提供亞洲字型的extrajars-2.2中的itext-asian.jar

他的做法是定義自己的parser, MyXMLParser p=new MyXMLParser(worker);並且為了支援中文,直接修改com.itextpdf.tool.xml.pipeline.html.HtmlPipeline的原始碼,感覺很黃很暴力。又去英文網站一通檢索,終於得到了一些啟發,沒有留存,就不表出處了。其中提到關鍵的一點說以前可以用XMLWorkerFontProvider來提供相應的字型,按照這個思路來說,也是可以提供中文字型進來的。研究了一下,選定com.itextpdf.tool.xml.XMLWorkerHelper來處理html流,傳入自定義的fontProvider來提供中文字型。

示例:

class myFontProvider extends XMLWorkerFontProvider {
  @Override
  public Font getFont(final String fontname, final String encoding,
    final boolean embedded, final float size, final int style,
    final BaseColor color) {
   BaseFont bf = null;
   try {
    bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
      BaseFont.NOT_EMBEDDED);
   } catch (DocumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   Font font = new Font(bf, size, style, color);
   font.setColor(color);
   return font;
  }
 }

處理程式碼:

  Document document = new Document(PageSize.A4, 30, 30, 30, 30);
  document.setMargins(30, 30, 30, 30);

  PdfWriter pdfwriter;
   pdfwriter = PdfWriter.getInstance(document,
     response.getOutputStream());
     document.open();
   XMLWorkerHelper wh = XMLWorkerHelper.getInstance();
   InputStream cssInput = null;
   wh.parseXHtml(pdfwriter, document, input, cssInput,
     new myFontProvider());
   document.close();

問題解決了,不需要修改原始碼,過載getFont來提供中文字型,改的還是比較粗暴,只提供了宋體一種字型,感興趣的可以根據fontname提供多種字型,時間所限就沒再嘗試了。html流要寫的標準,有不合標準的會報錯,具體看itext說明支援的xml標準即可。如果html流不是自己生成的,可以參考別人提到的一些轉換工具,我看到有jtidy類似的工具,沒研究過不做評述。