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類似的工具,沒研究過不做評述。