浏览 11852 次
锁定老帖子 主题:IText使用PDF模板输出报表的实践
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-12
最后修改:2009-07-14
本文所要用到的工具或jar主要有: Acrobat 8 这个主要用来制作PDF模板、eclipse这个看你喜欢咯(你用其他也行) 、 itext.jar、 还有为了解决中文的输出问题,需要多下载一个名为iTextAsian.jar的JAR包。这个包里面定义了与中文输出相关的一些文件。 好了,需要做的就是这些了,简单的PDF生成这里就不再作介绍了,本文主要讲解如何使用PDF模板。 我们先来看看制作出来的效果: ![]() 上图表格上及表格中的数据是动态添加进去的,页数为两页(为节约版面现只显示一页) 两页都是用的同一模板的, 1、 模板的制作: 我主要使用的是Acrobat8.0,上面所用到的模板是由 周工作报告 模板修改而来的,如果想学习如何新建一个新的模板,大家可以参照下这里吧! http://lxy19791111.iteye.com/blog/102848 2、 取得每个表单域的名字 模板制作好后,要插入数据首先就要知道需要插在模板中位置, //需要生成后的PDF FileOutputStream fos = new FileOutputStream("c:/test/Pdf.pdf"); //PDF模板路径 String TemplatePDF ="c:/test/PdfTemplate.pdf"; PdfReader reader = new PdfReader(TemplatePDF); PdfStamper stamp = new PdfStamper(reader,fos); AcroFields form = stamp.getAcroFields(); for (Iterator it = form.getFields().keySet().iterator(); it .hasNext();) { System.out.println(it.next()); } 这个是打印后的部分结果: ![]() 我们只取后面那个命名就行,如"星期四[3]" 当然,模板是你自己定义,文本域的命名你当然知道了,这里只是作个简单介绍而已。 3、下面是插入数据及PDF合并的代码: package com.golden.info.test; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.AcroFields; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; public class TestPdfTemplate { public static void main(String[] args) { try { int count = 8;// 总记录数 int pageCount = 4;// 每页记录数 int index = 1; // 表格序号 int page = 0;// 总共页数 /** 主要控制总共的页数*/ if (count >= pageCount && count % pageCount == 0) { page = count / pageCount; } else { page = count / pageCount + 1; } String TemplatePDF = "c:/test/PdfTemplate.pdf";//设置模板路径 FileOutputStream fos = new FileOutputStream("c:/test/Pdf.pdf");//需要生成PDF ByteArrayOutputStream baos[] = new ByteArrayOutputStream[page];//用于存储每页生成PDF流 /** 向PDF模板中插入数据 */ for (int item = 0; item < page; item++) { baos[item] = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(TemplatePDF); PdfStamper stamp = new PdfStamper(reader, baos[item]); AcroFields form = stamp.getAcroFields(); form.setField("DepartmnetNmae", "蓝飞");//插入的数据都为字符类型 form.setField("qq", "252462807"); form.setField("pageNumber", "第" + (item + 1) + "页,共" + page + "页"); if (count % pageCount != 0 && item == page - 1) { System.out.println("====pageCount+" + pageCount + "====="); pageCount = count % pageCount; } /**因为PDF中的表格其实是众多的文本域组成,就是一个数组,所以把它循环出来就可以了*/ for (int j = 0; j < pageCount; j++) { form.setField("ProjectTask[" + j + "]", index + ""); form.setField("星期一[" + j + "]", "星期一[" + index + "]"); form.setField("星期二[" + j + "]", "星期二[" + index + "]"); form.setField("星期三[" + j + "]", "星期三[" + index + "]"); form.setField("星期四[" + j + "]", "星期四[" + index + "]"); form.setField("星期五[" + j + "]", "星期五[" + index + "]"); form.setField("星期六[" + j + "]", "星期六[" + index + "]"); form.setField("星期日[" + j + "]", "星期日[" + index + "]"); form.setField("意见[" + j + "]", "同意[" + j + "]"); index++; } stamp.setFormFlattening(true); // 千万不漏了这句啊, */ stamp.close(); } Document doc = new Document(); PdfCopy pdfCopy = new PdfCopy(doc, fos); doc.open(); PdfImportedPage impPage = null; /**取出之前保存的每页内容*/ for (int i = 0; i < page; i++) { impPage = pdfCopy.getImportedPage(new PdfReader(baos[i] .toByteArray()), 1); pdfCopy.addPage(impPage); } doc.close();//当文件拷贝 记得关闭doc } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } } } 至于,生于PDF后,想打印出来,只要调用以下代码就行了 try{ Executable ex = new Executable(); ex.openDocument("c:/test/Pdf.pdf"); ex.printDocument("c:/test/Pdf.pdf"); }catch(IOException e){ e.printStackTrace(); } 到这里,运用上面的那些代码,就完成了PDF模板输出报表. (PDF模板、代码跟运行结果在附件里) 有错误之处请指正. 也希望这篇文章可以帮到您. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-12
你这个其实还是定制式的,要包装之后形成比较方便的控件更好
|
|
返回顶楼 | |
发表时间:2009-07-12
aws 写道 你这个其实还是定制式的,要包装之后形成比较方便的控件更好
请问还有更好的实现方式吗?希望你可以分享下你的实现方式 |
|
返回顶楼 | |
发表时间:2009-09-04
在实际的项目中,我们也使用到了itext,看中的是它的小巧和快速。
大概是这样做的:使用html标记语言定义了一套模板,使用到了一部分html的tag和属性,然后通过对模板的解析得到的就是一个不包含任何数据的内存模型,其中比较关键的是包含了业务数据的key(这个key是定义在模板中的)。至于数据,通过datasource的概念来实现,简单一点就是key-value的map,最后,通过一个生成器将PDF生成出来(就是讲模型转换成itext的实现过程)。 主要功能:自动分页,多页模板的支持,支持循环表,支持嵌套表。 |
|
返回顶楼 | |