环境介绍:
itext目前已经发展到itext7版本,目前系统里面使用的itext2版本;
使用spring的freemaker结合itext,完成pdf的导出
需要进行pdf导出的html文件,可能包含下面这几种情况,导致pdf导出失败:
针对上面的几个问题,解决思路:
1,研究itext代码,重写html解析相关的类
2,使用html处理工具,对html文件进行合法性处理(比如:jsoup)
选第二种方案(第一个费时间,没有太多的精力研究)
结合jsoup,对html文件进行处理,核心代码:
对html文件进行合法性处理
/**
* 1,html标签对齐
* 2,检查所有的img标签,如果为base64编码就去掉该图片
* 3,过滤所有的html标签,仅保留styles和class两个属性,其他的属性去掉
* 4,检查字体设置,如果有字体设置,但是没有SimSun字体,增加SimSun
* @param bodyHtml
* @return
*/
public static String correctBody(String bodyHtml){
if(bodyHtml==null || "".equals(bodyHtml)) {
return "";
}
//1,html标签对齐
Document doc = Jsoup.parseBodyFragment(bodyHtml);
//2,检查所有的img标签,如果为base64编码就去掉该图片
Elements elements=doc.getElementsByTag("img");
for(Element element : elements) {
String imgSrc=element.attr("src"); //获取src属性的值
if(imgSrc.indexOf("data:image")>-1){
element.attr("alt","该图片不支持导出");
element.attr("src"," ");
}else{
String width = element.attr("width");
int num = getNumber(width);
if(num==Integer.MAX_VALUE){
int realWidth = FileTool.imageWidth(imgSrc);
if(realWidth > 550){
element.attr("width","550");
}
}else if(num > 550){
element.attr("width","550");
}else{
//do nothing
}
}
}
//3,过滤所有的html标签,仅保留styles和class两个属性,其他的属性去掉
Whitelist wl = Whitelist.relaxed();
for(int i=0;i
关于图片的处理,从本地环境,获取图片的宽度
/**
* 计算width对应的宽度
* 如果没有宽度设置,设置为Integer.MAX_VALUE
* 否则就是width对应的宽度
* @param str
* @return
*/
private static int getNumber(String str){
StringBuffer sbuf = new StringBuffer();
int num = Integer.MAX_VALUE;
if(str != null && !"".equals(str)){
for(int i=0;i=48 && str.charAt(i)<=57){
sbuf.append(str.charAt(i));
}
}
if(sbuf.length()>0){
num = Integer.valueOf(sbuf.toString());
}
}
return num;
}
最终的处理:
public static String correctHtml(String bodyHtml){
// 1,html标签对齐
// 2,检查所有的img标签,如果为base64编码就去掉该图片
// 3,过滤所有的html标签,仅保留styles和class两个属性,其他的属性去掉
// 4,检查字体设置,如果有字体设置,但是没有SimSun字体,增加SimSun
String str = JsStringUtils.correctBody(bodyHtml);
// 5,填空题
str = str.replaceAll("(]+)(>)", "__________");
// 6,pdf要求严格的html
str = str.replaceAll("
", "
");
// str = str.replaceAll("(]+)(>)", "$1$2 />");
// str = str.replaceAll("(]+)(>)", "$1$2 />");
// 7,去掉多余的body
str = str.replaceAll("", "");
str = str.replaceAll("", "");
// System.out.println("-----------------------------------");
// System.out.println(str);
return str;
}