itext转PDF,富⽂本编辑器解决⽅案
关于itext转PDF的实现,⼤家可以看以下地址,如果不涉及富⽂本,上⾯的⽅案是⾮常棒,⽽且⾮常全的。我之前遇到的⼀些问题,在这个博客上都到解决办法了。
上⾯那篇 博客,也没有实现富⽂本内容转PDF。他说得不错,富⽂本对于itext转PDF来说,就是⼀场灾难。包括我的解决办法,也只是让富⽂本,在更多的情况下,PDF能下载成功,⽽且能正常打开,正常显⽰。
虽然他博客上说了⼀些要注意的,我还是再备注⼀下,itext转PDF需要注意的地⽅:
1.所有标签必须闭合,如<input /> <img /> <br />  (有时候html内容⾮常⾮常多,其实很难到哪⾥没闭合,这时候要头疼死,没关系,有解决办法的,firefox下载⼀个叫html validator的插件,配置⼀下,只看没有闭合的错误,其它的⼀些如该标签没有什么什么属性这些错误,不⽤管)
2.页⾯中不能出现   这是下载不成功的,把所有的   改成  
3.如果你页⾯中,有table代码,你的table记得在style中加⼀个属性:table-layout:fixed; word-break:break-strict;
4.上⾯博客中,说是<html>标签上⾯要加⼀个dtd,我个⼈试了下,加跟没加,没区别,反正我没加
5.你的页⾯中,可以引⼊css⽂件,可以写style标签,但⼀定要记得,<style></style>这个必须是放在head⾥,不然不能渲染你的样式。
6.你的标签属性,属性值必须以引号包含,如width="50",如不包含,会报错。
7.标签名称,如<td>,不能写成<TD>,⼤写的,在IE下载时,不兼容,会报错。
好了,只相得到这么多,纯⼿打,有别的问题,也欢迎沟通交流。
说下富⽂本吧
上⾯说的⼏条,基本上富⽂本都不会遵守,也就是说,即使你⾃⼰写的html没有问题,但富⽂本编辑器插⼊的html,还是会这样。
1.富⽂本不会帮你闭合你的标签,它只管显⽰正常,如<img /> <br/>,它会是<img >  <br>更有甚者,⽐如说tinymce,<br中间还会有很多⼀些它定义的东西。
2.富⽂本对于空格或者⼀些空⽩,会帮你转成  这是灾难的开始
3.⽤富⽂本拉出来的table,会帮你加各种样式,加各种宽度⾼度,即使能下载成功,也不能完全展⽰(当然,这个问题,⼀般的编辑器都⽀持你引⼊⾃⼰的css,我没试过,但应该可以控制)
asp富文本编辑器
4.
5.
6.这个问题就很严重了,说的是IE浏览器,它并⾮所有的属性值都不⽤引号包含,但有很多属性值都会直接width=50这样,很残忍(fuck ie)(我⽤的是IE8测的)
7.再说这个问题,也⾮常扯淡,富⽂本的内容,在IE上,输⼊完成,保存,保存时居然被转成⼤写了。
好吧,扯了这么多,现在说下富⽂本的解决⽅案吧。
我⽤的⽅案很简单,也很蠢,就是⼀个个地转,以下是我将html代码转成适合下载的html⽤到的,完全是发现⼀个问题,解决⼀个,也许还不全 ,后⾯应该还需要做些完善。
/**
* 基本过滤,主要过滤特殊字符与下载时不规则字符,过滤table样式
* @param result
* @return
*/
public static String reEscapeHtml(String result) {
String temp = result;
//匹配script整个标签的正则
final String scriptRegx = "(?i)(<SCRIPT)[\\s\\S]*?((</SCRIPT>)|(/>))";
//匹配换⾏的正则
final String brRegx = "(?i)(</*br.*?>)";
//空格
final String nbspRegx = "(&|&)nbsp;";
//table
final String tableRegx = "(?i)(<table (?!ignore=\"true\").*?>)";
//img
final String imgRegx = "(?i)(<img\\s.*?>)";
temp = placeAll(scriptRegx, "")
.replaceAll("\r|\n|\\r|\\n|\r\n|\\r\\n|\t|\\t", "")
.replaceAll(imgRegx, "")
.replaceAll(brRegx, "<br />")
.replaceAll(nbspRegx, " ")
.replaceAll(" ", " ")
.replaceAll(tableRegx, "<table class=\"cm_tb\" style=\"width:100%;table-layout:fixed; word-break:break-strict;\">")
;
return temp;
}
/**
* 标签转⼩写,转完⼩写,顺便补全引号
* @param temp
* @return
*/
public static String tagToLowerCaseAndComplete(String temp) {
//标签开始的匹配
final String tagRegx = "<[A-Za-z].*?>";
Pattern p = null;
Matcher matcher = null;
p = Patternpile(tagRegx);
matcher = p.matcher(temp);
while (matcher.find()) {
String value = up(0);
if (null == value || "".equals(value))
continue;
String tmpValue = LowerCase();
//⾃动补全引号,加这⾥⽽不加外⾯
tmpValue = reCompletionQuoat(tmpValue);
//tmpValue = removeWidthAndHeightInTag(tmpValue);
temp = replaceStr(temp, value, tmpValue);
}
//结束标签的匹配
final String tagEndRegx = "</[A-Za-z]+>";
p = Patternpile(tagEndRegx);
matcher = p.matcher(temp);
while (matcher.find()) {
String value = up(0);
if (null == value || "".equals(value))
if (null == value || "".equals(value))
continue;
temp = replaceStr(temp, value, LowerCase());
}
return temp;
}
/**
* ⾃动补全引号(接上⼀步的标签转⼩写)
* @param str
* @return
*/
public static String reCompletionQuoat(String tag) {
final String tagRegx = "([A-Za-z]+)=([^\"|\']*?)(>|\\s)";
Pattern p = Patternpile(tagRegx);
Matcher m = p.matcher(tag);
while (m.find()) {
String tmp = m.group(0);
String key = m.group(1);
if (null == key || "".im()))
continue;
String value = "\"" + m.group(2) + "\"";
String end = m.group(3);
tag = replaceStr(tag, tmp, (key + "=" + value + end));
}
return tag;
}
/**
* width="1024px"|width='1024px'|width:1024px|width:1024px;
* 对于width,上⾯的example都可以过滤,height与width同样规则
* 对于width="50%"这样的,是不过滤的
* @param tag
* @return
*/
public static String removeTableWidthAndHeight(String result) {
String widthAndHeightRegx = "(width|height)(=|:|\\s*?:\\s*?)(\"|\')*\\d+px(\"|\'|;)*";
/
/String tableRegx = "(?i)(<table (?!ignore=\"true\").*?>.*?</table>)";
placeAll(widthAndHeightRegx, "");
}
public static String replaceStr(String sourceStr, String targetStr, String insertStr) {
int index = sourceStr.indexOf(targetStr);
if (index == -1)
return sourceStr;
String preStr = sourceStr.substring(0, index);
String afterStr = sourceStr.substring(index + targetStr.length());
return preStr + insertStr + afterStr;
}
上⾯的removeTableWidthAndHeight这个⽅法我没有写全,因为后⾯富⽂本粘贴,换成了直接粘贴纯⽂本。这个⽅法,也只是在粘贴其它地⽅的富⽂本,贴到⾃⼰的编辑器的时候,会存在问题。
还有没完善的
如:富⽂本⾥,如这样的问题,还需要正则来做下过滤。
到了这个时候,如果你已经全部照做了,但是格式还是有问题,这个时候怎么办?我这个项⽬也没解决,但有⼀个⽅法是⾏得通的,就是你已经编辑好内容了,你就验证⼀下你的html是否能下载。
把下载PDF代码阉割⼀下,只要在render的时候异常,就说明你格式有问题。(⼤部分的操作,都是为了兼容IE浏览器)
------------------------分割线----------------------------
这个问题到此为⽌了。但事实上这不是我想要的解决⽅案。我相信很多⼈,包括我⾃已,都是这么说
replaceStr 上⾯我写了这个⽅法,很多⼈会说,我为什么不直接replaceFirst,原因就是因为我担⼼⼀些特殊字符,会被当成正则来匹配,导致匹配出问题,这时候直接限制了你前台的输⼊。我觉得这⾥
写越多的⽅法,来解决这个问题,就会暴露越多问题。这不是我想要的,我曾经提过⼀个解决⽅案,但是没通过。
这⾥我说下我想的解决⽅案。
htmlcleaner这个html分析的jar,相信很多⼈都⽤过。我曾经⽤过⼀段时间,挺不错的。
htmlcleaner我记得有⼀个操作,你将⼀段html转成TagNode的时候,再去把html代码拿出来,这⾥⾯⼤多数标签,都会闭合,都会是⼀个很完整的标签,是⼀段⽐较完美的html代码。因为项⽬中考虑到第三⽅jar包的安全问题,我只提了出来,但没有去试过,我隐约记得以前做爬⾍,htmlcleaner确实有这⽅⾯的操作的,感兴趣的朋友,可以去试⼀下。
⽽且,⽤htmlcleaner处理html元素,我相信,会⽐⽤正则处理字符串更好,不容易引发别的问题。有兴趣的朋友,可以试⼀下。
当然,我这⾥只是列举⼀个我⽤过的处理html的⼀个jar,你也可以⽤别的,原理都差不多。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。