一个是xhtmlrenderer
https://xhtmlrenderer.dev.java.net/
LGPL协议
另外一个是
http://www.allcolor.org/YaHPConverter/
LGPL协议
都是基于ITEXT的
2010-9-19注:
开始用YaHPConverter发现好像不支持标签,而且用起来很费劲,改用xhtmlrenderer感觉很舒服。
public class HtmlToPdfUtil { private HtmlToPdfUtil() { } private static Configuration cfg = new Configuration();// freemarks static { cfg.setObjectWrapper(new DefaultObjectWrapper()); cfg.setDefaultEncoding("utf-8"); try { cfg.setDirectoryForTemplateLoading(new File(ServletActionContext .getRequest().getRealPath("/WEB-INF/template/"))); } catch (IOException e) { throw new RuntimeException("设置模板路径错误!"); } } public static InputStream convert(String template, Map data) throws DocumentException, IOException, TemplateException { StringWriter sout = new StringWriter(); Template t = cfg.getTemplate(template); t.setEncoding("utf-8"); t.process(data, sout); ITextRenderer renderer = new ITextRenderer(); // 解决中文支持问题 ITextFontResolver fontResolver = renderer.getFontResolver(); fontResolver.addFont(ServletActionContext.getRequest().getRealPath( "/fonts/ARIALUNI.TTF"), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // fontResolver.addFontDirectory(ServletActionContext.getRequest() // .getRealPath("/fonts/"), BaseFont.NOT_EMBEDDED); renderer.setDocumentFromString(sout.getBuffer().toString()); // 解决图片的相对路径问题 renderer.getSharedContext().setBaseURL( new File(ServletActionContext.getRequest().getRealPath("/")) .toURI().toURL().toString()); System.out.println(new File(ServletActionContext.getRequest() .getRealPath("/")).toURI().toURL().toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); renderer.layout(); renderer.createPDF(out, true); return new ByteArrayInputStream(out.toByteArray()); } }
模板:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> body { font-family: Arial Unicode MS; } </style> <title>书皮</title> <style type="text/css"> @page { size: a4 portrait; margin: 20mm 10mm; padding: 1em; @top-left {content: element(header);} @bottom-left{content: element(footer);} @bottom-center{content: counter(page) " / " counter(pages);} @bottom-right{content: "www.quidos.co.uk";} } @page blank { size: a4 portrait; margin: 20mm 10mm; padding: 1em; @top-left { content: normal } @bottom-left { content: normal } @top-right { content: normal } @bottom-right {content: normal } @bottom-center{content: normal } } /*header as footer will automatically icluded in each pdf printed page*/ #header { position: running(header);} #footer { display: block; position: running(footer);} #pagenumber:before {content: counter(page);} #pagecount:before {content: counter(pages);} /* Used for generating Table of content */ #toc a::after { content: leader('.') target-counter(attr(href), page); } /* Use this class for first level titles */ .page_break_before{ page-break-before: always; } /* Use this class for forcing page break inside pdf */ .page_breaker{page-break-after:always;} .blank { page : blank; } </style> <bookmarks> <bookmark name="test1" href="#test1" /> <bookmark name="test2" href="#test2"> <bookmark name="test3" href="#test3"> </bookmark> <bookmark name="test4" href="#test4"> </bookmark> </bookmark> </bookmarks> </head> <body> <div style="font-family: Arial Unicode MS;" id="test1"> <input name="testInput" type="hidden" value="test value" /> <p> 项目编号: <span style="border-bottom: black solid 1px;">{xiangmubianhao}</span> </p> <p> <span style=""><br/> </span> </p> </div> </body> </html>