转载:http://blog.sina.com.cn/s/blog_71d09f5f0101bi8g.html
工作需要,把一些表格以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
查了些资料,参考:http://cczlg.blog.163.com/blog/static/3399831920115221167605/
他的做法是定义自己的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类似的工具,没研究过不做评述。