昨天研究html转pdf,使用itextpdf 5.5.9版本(上一篇博客:https://my.oschina.net/u/1778261/blog/809757)
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itextpdf.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>${itext.asian.version}</version>
</dependency>
中文显示问题解决了,当时碰到了打印表单中input框等不显示的问题。
今天换了个方案使用flying-saucer 实现html转pdf
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.1</version>
</dependency>
实现代码如下:
public void html2pdf(String html, File file, String fontDir) throws I18NIllegalArgumentException {
try (OutputStream os = new FileOutputStream(file); ){
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = (ITextFontResolver) renderer.getSharedContext().getFontResolver();
//添加字体库 begin
File f = new File(fontDir);
if (f.isDirectory()) {
File[] files = f.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
String lower = name.toLowerCase();
return lower.endsWith(".otf") || lower.endsWith(".ttf") || lower.endsWith(".ttc");
}
});
for (int i = 0; i < files.length; i++) {
fontResolver.addFont(files[i].getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
}
//添加字体库end
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(os);
} catch (Exception e) {
throw new I18NIllegalArgumentException(e);
}
}
网上查的都是添加字体的方法都是这样实现的:
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);
这样实现有个缺陷:字体的路径都是系统的目录,不同系统(windows,Linux)字体目录不同,对系统依赖太高。
为了解决这个问题:找到字体库文件,复制到项目的目录中,在代码中直接遍历这个目录,添加所有的字体。
注意:页面中字体不能使用中文,需要使用英文名称,而且是大小写敏感的!例如宋体的英文名称是 SimSun(注意不是simsun!,首字母都是大写的)
错误写法:font-family:'宋体' 或者 font-family:'simsun' 或者 font-family: '微软雅黑'
正确写法:font-family:'SimSun' 或者 font-family:'SimHei'或者 font-family: 'Microsoft YaHei'
另外: html的格式要求符合xml格式(即必须有结束标签)
测试:
测试用html代码:
<!DOCTYPE html>
<html>
<head>
<title>我是标题</title>
<meta charset="utf-8"/>
<style type="text/css">
*{font-family: 'SimSun';}
</style>
</head>
<body>
<input type="text" name="name" style="line-height: 1;height: 30px; width: 300px; font-size: 12px;" value="I am 输入 input" readonly="readonly" />
<textarea disabled="disabled">我是内容</textarea>
<select disabled="disabled"><option>asdfsdf今晚打老虎</option></select>
<input type="checkbox" name="hobby" value="运动" disabled="disabled"/>运动<input type="checkbox" name="hobby2" value="睡觉" checked="checked" readonly="readonly"/>睡觉
</body>
</html>
html浏览器显示结果:
生成的pdf: