关于使用itext和freemarker你可能会遇到的一些问题,这里都有!!!

前段时间做了一个项目需求,需要将网页中间显示的一块内容转成PDF文档供用户下载。完成这个需求的过程中使用到了itext和freemarker,中间遇到了不少问题,这里分享一下,希望可以帮助到遇到同样问题的朋友。

 

首先,先总结一下遇到过得一些问题吧。

1. PDF中中文不显示

2. 长英文字符串不换行

3. 添加的字体文件编译、打包之后损坏,字体文件变大,导致字体不可用

4. 将<XXX>识别为HTML标签,导致HTML显示不全,生成PDF失败

5. 关于freemarker

 

以上的话,就是目前能想到的一些问题,如果后续有想到的话再补充。在进行以上问题的解答之前,先说一下用到的jar包吧。本次供使用了两个jar包,一个是freemarker的jar包,用于数据渲染,生成HTML;另一个是html2pdf的jar包,用于将生成的HTML转成PDF文件。

以下是添加jar包的截图:

1. 关于中文不显示的问题

有两种解决办法,一种是添加支持中文显示的字体文件,另一种是添加中文的字体包itext-asian。由于使用字体包生成的PDF显示效果不是很好,所以本次方案中并没有采用这种方案,但是后面会在附录中对这种方案的使用进行一个演示,下面重点来说一下添加字体文件的方式。

重点看一下红色框框里的内容,是与字体设置相关的,fontDir就是我们存放字体的目录,我是将字体文件放在resources下面的fontDir文件夹下面的。

 

2. 长英文字符串不换行

先给大家看一下没解决之前的展示吧,如下图所示:

一开始百度搜索换行问题显示的时候,网上给出的都是关于HTML中的换行操作,如word-break: break-all; word-wrap: break-word。我也照着做了,但是,这也仅仅能解决生成的HTML页面显示中长英文字符串换行的问题,根本无法解决生成的PDF中换行的问题。没办法,只能自己琢磨看看是不是有什么可用的函数。然后,我注意到,在Document的类里面提供了一个函数似乎有控制换行的功能,也就是setSpiltCharacter();从函数名可以看到他时可以控制分割的字符。但是具体怎么使用呢?

这里教大家一招,也许在以后的开发工作中也许会使用到。首先,这个函数里面要传入的是一个ISpiltCharacters的接口或其实现类的对象。然后,我们可以看到,这个接口有两个实现类,如下:

首先,我们看一下在DefaultSplitCharacters实现类里面是怎么操作的,如下:

然后,再看一下NoSplitCharacters实现类里面是怎么操作的,如下:

使用这两个函数具体是什么效果我就不对比演示了。从函数的命名上我们大概也能明白其中的道理。所以为了使长英文字符串能够换行,我们必须实现isSplitCharacter()这个函数,允许换行的字符返回true。为了使英文字符、符号处换行,就设置Unicode编码小于128的返回true,下面是我实现的:

 

3. 添加的字体文件编译、打包后损坏,字体文件变大

这个主要是因为maven在编译文件的时候,会对文件进行过滤,会将${xxx}的值替换为配置文件中设置的值。为了使字体文件编译后的数据不被替换,需要将字体文件的过滤属性设置为false下:

但是,在这里设置只能保证编译之后的字体文件不被破坏,但是打包的话,字体文件还是变大了。在百度上也搜索到很多解决方案,但是语句位置不对,并没有起作用,这里也是浪费了很多时间。后来还是通过官方文档,才把问题解决,这里还是希望大家以后遇到问题的时候,还是要看一下官方文档,当然,百度也是有必要的,有助于理解。这里附上maven配置的官方文档http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html.

废话不多说,为了使打包后的字体文件不被破坏,需要加入以下代码:

 

 

 

4. 将<XXX>识别为HTML标签,导致HTML显示不全,生成PDF失败

这个问题是这样的:字符串里有这样的一串字符“xxxxx Map<String,String> xxxxxxxxxxxxxxxx”;由ftl模板与数据融合生成HTML的时候,会把<String,String>当做HTML标签处理(其实主要是“<>”的原因);因此,必须将字符串中这些类似HTML的标签忽略掉,不做处理操作很简单,只要熟悉一下freemarker语法就可以了。操作很简单,

这个语句的意思就是,如果header.c_explain存在的话,就不处理其中的HTML标签。

 

5. 关于freemarker

这里的话不想介绍太多很多关于freemarker的语法,需要的话可以再去学学。这里需要说的是,在引入变量的时候,最好是对该值是否存在进行一下判断,避免由于变量不存在导致解析出错,程序崩了。如取值为null时,则会报异常 freemarker.core.InvalidReferenceException,解决办法可以是:

(1)${name!""},表示如果name为null时,就将该值设为空字符串

(2)${name?if_exists?html} 表示name为null时不输出,不为null时才输出

 

 

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值