Boss给了我工作以来的第一个任务:在Java Application里面做个报表。一开始Boss强烈要求用水晶报表做,虽然我对那个一点概念也没有,但还是无奈的水晶报表的API。经过了一个星期的努力,终于被我找到了,但是做出来的结果让人很失望,Boss看了使劲的摇头,还说了一句,到时候不行的话就放弃这个项目吧。。。。郁闷,第一次任务就失败了吗?
后来跟Boss了解一下需求,发现其实要求也很简单,只要能显示报表(最好还能操作一下报表数据),然后还能打印出来(生成PDF然后打印就OK拉)。一开始我觉得前面一个需求很简单,用JTable显示就可以了,后面一个,上网上找个PDF的API就行了。
经过一轮的苦苦寻找,终于找到了iText,一套开源的Java处理PDF/RTF/HTML的API,并且它开源的要求不是那种基于它开发的也要全部开源,完全满足了我的要求。iText还有专门处理表格的类,用来做报表就最合适了。
用iText主要需要解决3个问题:
1、要知道一些基本的生成PDF的流程,会使用几个基本的类,包括PdfPTable,PdfPCell,Document,Font等(我就用这几个类而已)。生成一个PDF的基本流程是:
doc = new Document(PageSize.A4, 50 , 50 , 50 , 50 );
PdfWriter.getInstance(doc, new FileOutputStream(file));
// 设置页码
HeaderFooter hf = new HeaderFooter( new Phrase( " 第 " ,pageNumFont), new Phrase( " 页 " ,pageNumFont));
hf.setBorder(Rectangle.NO_BORDER);
hf.setAlignment(Element.ALIGN_RIGHT);
doc.setFooter(hf);
doc.open();
doc.add(Paragraph);
doc.add(PdfPTable);
doc.close;
设置页码要在PdfWriter获取实例之后,doc open之前设置。最后要把doc close了才能真正的生成需要的PDF文件的。
2、PDF中显示中文的问题。iText默认的jar包是不支持中文输出的,需要下载一个额外iTextAsian.jar才支持中文显示。(iText跟iTextAsian.jar在sourceforge上都可以下载)
Font titleFont = new Font(cnBaseFont, 20 , Font.BOLD);
Font typeFont = new Font(cnBaseFont, 12 , Font.BOLD);
Font pageNumFont = new Font(cnBaseFont, 9 , Font.BOLD);
要注意的是,下面那个Font不是java.awt.Font,而是com.lowagie.text.Font。要是在同一个类里面需要用上这2个包的Font,就要连包名也加上去了。
PdfPTable innerTable = new PdfPTable(n);
innerTable.addCell();
.
.
.
// 一共add了n*m个
PdfPCell cell = new PdfPCell(innerTable);
cell.setColspan(n);
table.addCell(cell)
出来的效果就是那个“跨行的单元格”跨了m行。
用iText的老式Table是有个跨行的方法的,但是我用它生成跨页的的表格的时候,总是会出现单元格截断的问题,即使用它的方法设置避免单元格/表格跨页截断的问题也不行。所以还是用较新的PdfPTable类吧,表格嵌套也不是很难写代码吧。
打印那块做好了,才发现在程序里面显示是比较难的——JTable标题栏跨行是很难做到的。在网上找了好多的源码,都是直接跑到最基本的绘制组件那个方法里面改。这样改,复杂就不说了,最重要的是这样好像还不能动态的生成标题栏,而且JTable有多个实例的时候,显示就不正常。算了算了,与其研究人家的代码,还不如自己写。但是那个高深的方法我是写不出来的,汗。。。
这个时候,Boss给了我一点意见,说Swing里面有个Html的控件(他好像不是这样说的),然后JEditorPane就出场了。JEditorPane可以解析html代码(不一定是完整的html文件),由于以前做过一些网页,知道html里面的table很好用,就用html的table做前台显示。实现起来也不难,就是在程序里写html代码(汗!)。尽管看起来很烦,但是用html实现的话,表格的外观比较好控制。最终做出来的界面,Boss连说几个“好”(个人认为其实也不是太好,不过比JTable那样死板的外表,确实colorful了很多^-^)。
后来发现这样的话,还只是显示好看了一点,功能还是就只有显示!我就给标题栏每个列都加了个超链接,一点就进行排序,功能就不那么单调了。写排序算法的时候,用2个小时还是写不出快速排序算法(^-^!),刚毕业就把东西都忘了。。。最终用1分钟写了个冒泡就完事了,反正排序的数据量又不大,并且只对索引排序而已,效率还是挺高的,嘿嘿。
工作的第一次任务就这样差不多结束了(还要等客户验收呢),感觉这一次学了不少东西,为了不让自己忘记所学的东西(偶没什么记性),就把它们都写下来了。