`

学习iText问题总结

阅读更多

      这两天开始学iText做pdf报表了。

 

      我以前都是用ireport设计报表的,不敢说会用,但起码略懂(还曾设计过某特著名高校的本科生学位证、毕业证等)。最近设计的pdf报表的问题却把我搞的无从下手:有些field中的文字是重叠出现的,不是某个field全是这样,是偶尔出现。

 

         没法子,只能改了。决定用iText,虽然说jasper封装的是iText,但还是要试试。万幸,用了iText,这个问题没有再出现了。

 

      下面说说这两天用iText解决的以及没解决的问题(我下载的是itext-5.1.0):

     

      1.错误信息:com.itextpdf.text.DocumentException: Font "STSongStd-Light" with "UniGB-UCS2-H" is not recognized。这是因为亚洲字体包没引入或引入了老版本的亚洲字体包(我当时就是从ireport中直接拿来这个包的,ireport用的是iText2.1.7,所以这个亚洲字体包是老版本的)。iText从5.0更改了包名,和以前的亚洲字体包不配套了。 去http://sourceforge.net/projects/itext/files/extrajars/下载extrajars-XX.zip,新的亚洲字体包就在这里面。请参照iText中的notice.txt文件。

 

          2 .用table.getDefaultCell()设置的属性,并没有实现预想的效果。这个问题就没搞定,最后逐一设置的cell的属性。

 

          3.大表格加入内存回收功能后,部分页面没有表头或多个表头。这个问题可就“神奇”了。首先,它居然把我不停地报内存溢出的问题搞定了(呵呵,这是它的功能所在,也是必须的);其次,居然有些页面没有表头。代码如下所示: int fregmentSize = 1017;// 定义每一段落的行数(用于释放内存) for (int i = 0; i < dataList.size(); i++) { if (i % fregmentSize == fregmentSize - 1) { document.add(table); table.deleteBodyRows(); table.setSkipFirstHeader(true); } ………… }


 

本来我定义的 fregmentSize 值是100,结果发现有些页面没有表头。这是因为清理table时正好达到页尾,即下一条数据需要在新的一页显示。这时table.setSkipFirstHeader(true)设置了表头不显示……悲剧了。可是如果设置显示表头table.setSkipFirstHeader(false),那么每次清理表格就会显示一次表头(pdf中就会一页中显示多个表头),显然更不合理。最后更改了fregmentSize 的值,以减少这样事情的发生。希望有解决这个问题的朋友能给留个解决方法。

 

 

 

 

 

 

 

 

      4.在学习中会有一些例子中遇到RtfWriter2、HtmlWriter就不要深研究了。因为这两东西从5.0已经从itext中独立出来了。我在网上好不容找到iText-rtf包,还是老版本的,没下载。sourceForge中有这个项目,但却没有提供jar,有个svn项目:

svn co https://itextrtf.svn.sourceforge.net/svnroot/itextrtf itextrtf 

这个项目使用iText2.1.8.jar编写的。仍与5以上的版本不配套(如HeaderFooter类5以上的版本已经取消,这个项目中仍在使用)。弄到这里我就不想在看这些包了,后面的HtmlWriter包就真的没看。

(HtmlWriter的东西在xmlworker-x.y.z.jar中,仍参照itext的notice.txt文件。例子:http://demo.itextsupport.com/xmlworker/doc.html)

 

下面是我学习时在网上收集的一些资料。整理一下,贴到下面。

百度文库(中文教程):http://wenku.baidu.com/view/dbafbbc66137ee06eff918a5.html

旧版本的demo:http://www.roseindia.net/java/itext/index.shtml

页头页脚demo:http://www.coderanch.com/how-to/java/ItextExample

<!--EndFragment-->

分享到:
评论
6 楼 Today_IT 2014-10-29  
好像导出word文档新建的Table对象(不是PDFTable),这个对象好像就没有table.deleteBodyRows(); table.setSkipFirstHeader(true);这两个方法哦!这时候该怎么办!?新建PDFTable和Table一样!?
5 楼 nobody2008 2013-11-18  
ae6623 写道
在读<<iText in Action 2nd>4.3节(Dealing with large tables)的时候,书上写道:itext5PdfPTable实现了ILargElement的接口,只需要我们手动设置datatable.setComplete(false);之后,它就可以自动将表格元素输出到document中,但是,对,就是这个但是!!我们的cell之多,多到它来不及去放进去,比如我并发100个线程去访问它,别说tomcat受不了,was也照样挂掉,给他8个G,它也照样吃掉,而且服务卡死。你说这样的产品放出去,我放心不?

于是,我大量Google,大量百度,大量Csdn,大量JavaEye,多少次的说多了都是泪,最后,yes,就是最后,我Tm什么法子都想了,list清空,指针赋null,优化程序循环,优化bufferedOutPutStream输出,优化下载,就差给Itext作者写信了!!

然后无名小卒兄居然也遇到了这个问题,而且这个博客我都不知道怎么搜到的,他中间用到了自己写的一个方法,根据行号去定次数,比如定义1000行一次释放table,将table先放到document,正好document中查到了你的table用datatable.setComplete(false)方法,于是它就开始往文件里面搬运数据,之后,我们删掉这些已经放进去的元素,用table.deleteBodyRows();好,这样产生了一个新的问题,就是每隔1000行,产生一个表头,于是无名兄又用到了table.setSkipFirstHeader(true);ok至此,解决全部问题,但是后续问题,无名兄遇到了,万一某一行刚刚好是最后一页,那么后续的表格没有了表头,这个问题我没遇到,因为我用到了另一个方法,就是  datatable.setHeaderRows(headerRows);// 设置头几行为表头(已经判断好了前几行为表头),这样我们就搞定了这个itext内存溢出的大问题!!也许很多人都不会遇到这个错误,但是我保证这个内存溢出会让你恨死Itext,现在好了,有了这个解决方案,就是几千万人并发又如何?代码稍后贴出。

落雨(感谢无名兄给的很好的思路!!先添加了再删掉再添加。good)
394263788
2013年9月11日 10:04:12

代码等:http://hi.baidu.com/ae6623/item/1e77cd3f3615cfbc623affe7



这两年多没来多iteye,今天来下载我上传的lucene in action。看到这些留言很感动,真的很感动

以后我会常来,更加认真地写一些东西。
感谢落雨。
4 楼 ae6623 2013-09-11  
如果有换页的情况(刚好上一页有本条的一部分数据,下一页页头又一部分本条数据),刚好设置了不在一页全部显示,放到下一页显示的时候,下一页此条数据丢失,暂时解决了,这个实在太奇葩了。。。就这样了,解决内存溢出就是一个大问题了。哦呵呵。。望知道怎么解决itext在setSplitRows(false)之后丢弃了行太高的某行数据的童鞋联系我,谢谢。394263788,我在网上查到是因为setSplitRows这个方法确实会丢弃数据。我搞了一下午,就不搞了,我把它最后一行的所有Row对象里面的Cell拿出来又如何。还是拆分表格到下一页吧,这样的话也不至于打印的时候空白太多,最后,再次感谢无名兄。我也在北漂中。
3 楼 ae6623 2013-09-11  
如果有换页的情况(刚好上一页有本条的一部分数据,下一页页头又一部分本条数据),刚好设置了不在一页全部显示,放到下一页显示的时候,下一页此条数据丢失,正在解决中。。。。。。

2 楼 ae6623 2013-09-11  
在读<<iText in Action 2nd>4.3节(Dealing with large tables)的时候,书上写道:itext5PdfPTable实现了ILargElement的接口,只需要我们手动设置datatable.setComplete(false);之后,它就可以自动将表格元素输出到document中,但是,对,就是这个但是!!我们的cell之多,多到它来不及去放进去,比如我并发100个线程去访问它,别说tomcat受不了,was也照样挂掉,给他8个G,它也照样吃掉,而且服务卡死。你说这样的产品放出去,我放心不?

于是,我大量Google,大量百度,大量Csdn,大量JavaEye,多少次的说多了都是泪,最后,yes,就是最后,我Tm什么法子都想了,list清空,指针赋null,优化程序循环,优化bufferedOutPutStream输出,优化下载,就差给Itext作者写信了!!

然后无名小卒兄居然也遇到了这个问题,而且这个博客我都不知道怎么搜到的,他中间用到了自己写的一个方法,根据行号去定次数,比如定义1000行一次释放table,将table先放到document,正好document中查到了你的table用datatable.setComplete(false)方法,于是它就开始往文件里面搬运数据,之后,我们删掉这些已经放进去的元素,用table.deleteBodyRows();好,这样产生了一个新的问题,就是每隔1000行,产生一个表头,于是无名兄又用到了table.setSkipFirstHeader(true);ok至此,解决全部问题,但是后续问题,无名兄遇到了,万一某一行刚刚好是最后一页,那么后续的表格没有了表头,这个问题我没遇到,因为我用到了另一个方法,就是  datatable.setHeaderRows(headerRows);// 设置头几行为表头(已经判断好了前几行为表头),这样我们就搞定了这个itext内存溢出的大问题!!也许很多人都不会遇到这个错误,但是我保证这个内存溢出会让你恨死Itext,现在好了,有了这个解决方案,就是几千万人并发又如何?代码稍后贴出。

落雨(感谢无名兄给的很好的思路!!先添加了再删掉再添加。good)
394263788
2013年9月11日 10:04:12

代码等:http://hi.baidu.com/ae6623/item/1e77cd3f3615cfbc623affe7
1 楼 ae6623 2013-09-11  
大表格加入内存回收功能,怎么加的 楼主?我在5800 * 32 列的一个table里面内存溢出啊!!!!我都想给Itext写信的节奏了!!大量的HashMap没有释放掉啊,这都是Itext里面搞的。。我的内存飙升到2G都不能解决这个问题。。。(15人并发下内存溢出,itext)

相关推荐

Global site tag (gtag.js) - Google Analytics