`
smvcn
  • 浏览: 34974 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

依样画葫芦实现JasperReport客户端本地打印

    博客分类:
  • Java
阅读更多

公司的项目需要在客户端直接打印出报表,之前还很轻松地认为这个实现起来不难,Jasper的api里不就有直接打印的方法吗?等照着api把方法用上测试的时候才发现,在客户端点“打印”按钮结果去调服务器的打印机,当时就知道自己高兴得太早了。没办法只好去百度,找来找去发现都是同一篇,在想了很久之后以自己目前的水平实在想不出除了那篇教程上说的用applet接收服务端的输出流之外还有别的什么能做到,于是决定照着例子做。然而结果比前次更凄惨,applet完全不运作。那时候一边想着自己是不是太笨了连依样画葫芦都干不好一边嘀咕那些转载例子的人到底有没有真正实践过那方法到底能不能用呀?
如此郁闷了一个晚上之后,第二天早上起来突然想到为什么不去看Jasper自带的例子?兴冲冲赶到公司一试,哎,真的弹出权限错误提示了。于是再骂一次自己是笨蛋,把例子改改套到程序上去了,这次终于搞定了。
总结这次的任务,一是遇到难题的时候最好找官方的资料,尤其是java的开源项目,那些domo大多都是精华;二是一定要多想想为什么,为什么demo会这么写?有什么道理?三是多动手实践,“实践是检验真理的唯一标准”,尤其是对我这个非计算机专业毕业的初学者来说:)

好了,废话说的够多了,下面来整理一下《实现JasperReport客户端本地打印》的要点(貌似这个才是我写这篇的重点,呵呵)

一、项目需求
点击打印图标弹出小窗口,窗口中有两个按钮,一个是“打印”,一个是“完成”,两个按钮上方是提示语句和提示图标。按下打印按钮后提示语句和提示图标改变,同时本地打印机开始打印。打印结束后按完成按钮完成本次打印。
(其实我的工作重点在于按下打印按钮之后到打印开始打印为止,其他的活是其他组员的任务)

二、实现过程
1、在servlet中得到JasperPrint对象,并将之写入ObjectOutputStream中
这一步没什么好说的,想怎么实现就怎么实现,总之得到一个JasperPrint对象,然后放进Objuect输出流里输出,最后达到运行servlet会弹出一个下载窗口的结果就OK。
这里给出比较关键的步骤:

java 代码
  1. /*  
  2. *这只是一些重点提示,甚至不是一个例子  
  3. */  
  4.   
  5. private static final String CONTENTTYPE = "application/octet-stream";   
  6.   
  7. public void doPost(HttpServletRequest request, HttpServletResponse response)   
  8.             throws ServletException, IOException {   
  9.     response.setContentType(CONTENTTYPE);   
  10.     ServletOutputStream ouputStream = response.getOutputStream();   
  11.     try {   
  12.         ObjectOutputStream oos = new ObjectOutputStream(ouputStream);  
  13.         //这里是调用了另外一个servlet,其结果也是返回一个JasperPrint对象    
  14.         JasperPrint jpt = rst.getReportPrint(rptCode, context,object, tradeTypeInput); 
  15.         oos.writeObject(jpt);   
  16.         oos.flush();   
  17.         oos.close();   
  18.     } catch (ReportException e) {   
  19.         //处理   
  20.     }  

2、用applet接收servlet传出的JasperPrint对象
这个,根本就是照抄JapserReport的demo源码了,稍微做了一些改动(比如去掉了预览、不需要按打印按钮直接打印)
代码如下:

java 代码
  1. package report.web;   
  2.   
  3. import java.io.PrintWriter;   
  4. import java.io.StringWriter;   
  5. import java.net.URL;   
  6.   
  7. import javax.swing.JOptionPane;   
  8.   
  9. import net.sf.jasperreports.engine.JasperPrint;   
  10. import net.sf.jasperreports.engine.JasperPrintManager;   
  11. import net.sf.jasperreports.engine.util.JRLoader;   
  12.   
  13.   
  14. /**  
  15.  * @author Teodor Danciu (teodord@users.sourceforge.net)  
  16.  * @version $Id: PrinterApplet.java 1229 2006-04-19 13:27:35 +0300 (Wed, 19 Apr 2006) teodord $  
  17.  */  
  18. public class JRPrinterApplet extends javax.swing.JApplet   
  19. {   
  20.   
  21.   
  22.     /**  
  23.      *  
  24.      */  
  25.     private URL url = null;   
  26.     private JasperPrint jasperPrint = null;   
  27.   
  28.   
  29.     /** Creates new form AppletViewer */  
  30.     public JRPrinterApplet()   
  31.     {   
  32.            
  33.     }   
  34.   
  35.   
  36.     /**  
  37.     *  
  38.     */  
  39.     public void init()   
  40.     {   
  41.         String strUrl = getParameter("REPORT_URL");   
  42.         if (strUrl != null)   
  43.         {   
  44.             try  
  45.             {   
  46.                 url = new URL(getCodeBase(), strUrl);   
  47.             }   
  48.             catch (Exception e)   
  49.             {   
  50.                 StringWriter swriter = new StringWriter();   
  51.                 PrintWriter pwriter = new PrintWriter(swriter);   
  52.                 e.printStackTrace(pwriter);   
  53.                 JOptionPane.showMessageDialog(this, swriter.toString());   
  54.             }   
  55.         }   
  56.         else  
  57.         {   
  58.         JOptionPane.showMessageDialog(this"Source URL not specified");   
  59.         }   
  60.     }   
  61.   
  62.     public void start() {   
  63.         if (url != null)   
  64.         {   
  65.             if (jasperPrint == null)   
  66.             {   
  67.                 try  
  68.                 {   
  69.                     jasperPrint = (JasperPrint)JRLoader.loadObject(url);   
  70.                 }   
  71.                 catch (Exception e)   
  72.                 {   
  73.                     StringWriter swriter = new StringWriter();   
  74.                     PrintWriter pwriter = new PrintWriter(swriter);   
  75.                     e.printStackTrace(pwriter);   
  76.                     JOptionPane.showMessageDialog(this, swriter.toString());   
  77.                 }   
  78.             }   
  79.                
  80.             if (jasperPrint != null)   
  81.             {                  
  82.                 final JasperPrint print = jasperPrint;   
  83.                    
  84.                 Thread thread = new Thread   
  85.                     (   
  86.                         new Runnable()   
  87.                         {   
  88.                             public void run()   
  89.                             {   
  90.                                 try    
  91.                                 {   
  92.                                     JasperPrintManager.printReport(print, true);   
  93.                                 }   
  94.                                 catch (Exception e)    
  95.                                 {   
  96.                                     StringWriter swriter = new StringWriter();   
  97.                                     PrintWriter pwriter = new PrintWriter(swriter);   
  98.                                     e.printStackTrace(pwriter);   
  99.                                     JOptionPane.showMessageDialog(null, swriter.toString());   
  100.                                 }   
  101.                             }   
  102.                         }   
  103.                     );   
  104.                    
  105.                 thread.start();   
  106.             }   
  107.             else  
  108.             {   
  109.                 JOptionPane.showMessageDialog(this"Empty report.");   
  110.             }   
  111.         }   
  112.         else  
  113.         {   
  114.             JOptionPane.showMessageDialog(this"Source URL not specified");   
  115.         }   
  116.   
  117.     }   
  118.        
  119. }   

3、打包applet的class和所需的jar包,并加上数字签名
要运行这个applet需要jasperreports-1.2.8-applet.jar(后来我想了一下,之所以照抄网上的例子不能成功的原因,很有可能是导入的jar包不对,这个工作是之前的程序员做的,他导入的包当中没有applet这个),可以用winrar直接解压缩了,然后把applet编辑后的class和解压缩后的文件放在同一个目录(比如temp),在命令提示符中输入 jar 命令打成一个包,例如:jar -cvf reportprint.jar *
接着开始做数字签名:
1)用keytool生成证书:keytool -genkey -alias mykey -keystore mystore
2)还是用keytool导出证书:keytool -export -keystore mystore -alias mykey -file my.cer
3)用jarsigner给reportprint.jar加上数字签名:jarsigner -keystore mystore reportprint.jar mykey
以上都是在命令提示符下运行,mykey和mystore都可以以自己的命名方式来命名
现在在temp下已经有了一个reportprint.jar和一个my.cer,把这两个文件拷贝回项目中,记得还是放在同一个目录下

4、用Ajax连接页面和servlet
弹出的打印小窗口中不需要把applet加载进去,等按下打印按钮之后再用innerHTML的方式加载,比如:

js 代码
  1. //还是一样,这个不是例子,只是重点提示   
  2.   
  3. var print = document.getElementById("printtest");   
  4. var path = //这里是servlet的地址;   
  5. print.innerHTML = "……" //这里是加载applet的代码,貌似这里直接给出会出错,那么去看JasperReport给的例子好了,例子名称是webapp<noembed></noembed>

 

5、测试打印
按下打印按钮后会出现是否运行签名的提示,允许之后就会弹出系统自带的打印对话框。如果不想弹出打印对话框直接在打印机上打印,那么在applet中把JasperPrintManager.printReport(print, true); 改成JasperPrintManager.printReport(print, false);就好,JasperReport的api里有说明

三、环境要求
需要客户端安装Jre1.5,并且IE选项高级里,必须将“将JRE1.5.x.xx用于applet(需要重启动)”勾选上才行。
在window+IE6.0中运行通过。

至此,用JasperReport在客户端实现本地打印完成。

(其实是组长要求我写技术文档,一开始根本毫无头绪,想拿写blog练练手,写完之后发现思路清晰多了,现在继续和文档搏斗去了,呵呵)

分享到:
评论
6 楼 wsxjq 2012-03-14  
你这个还好,我们公司的要求更过分,要使用本地打印机批量打印客户端的文件!不知道是否有好的建议!
5 楼 wsxjq 2012-03-14  
你这个还好,我们公司的要求更过分,要使用酝打印机批量打印客户端的文件!不知道是否有好的建议!
4 楼 yuanfen127 2008-01-12  
你这里的rst是什么东西啊?第一段代码不正确哦
3 楼 liyong_2003_cn 2007-12-11  
adverse 写道
楼上的意思是不是说,客户端没有安装jre或者版本不够高,提示自动下载,我记得是加个basecode,指明版本.这样会自动检测客户端的jre是否满足要求。
jar文件可以用codebase来引用,但是自动安装jre我见过润乾报表是实现了的,把jre的安装文件也打到war包中,当需要的时候,自动弹出安装提示,比较方便.
2 楼 adverse 2007-12-11  
楼上的意思是不是说,客户端没有安装jre或者版本不够高,提示自动下载,我记得是加个basecode,指明版本.这样会自动检测客户端的jre是否满足要求。
1 楼 fight_bird 2007-08-06  
对于数据安全有要求的报表,用applet打印可能是较好的方式,可惜要装jre1.5,好像能够实现ie中自动安装本地网络中的sun的java插件的功能,谁实践过?

相关推荐

    WheelView源码简单的依样画葫芦

    **WheelView源码解析与实现** `WheelView`是一种在Android平台上常见的滚动选择器控件,通常用于日期选择、选项滚动等场景。本篇将深入探讨`WheelView`的源码,通过实例来理解其工作原理,从而为自己的项目提供...

    Essential.cpp

    一本实用的关于C++编程的学习指导书,篇幅较短,适合想短期熟悉c++的学习者

    利用Cloudera Manager API来自动监控CDH大数据组件并异常自动重启恢复的代码(亲测可用)

    HBaseRegionServerMonitor 是检测hbase regionServer挂掉并自动重启,可依样画葫芦检测hdfs、spark等大数据组件。 AutoRoleMonitor是升级版,会自动检测CDH集群下所有的服务,有哪些服务挂了,并根据大数据组件的...

    支付宝新版SDK AliPayEasy.php

    本人线上项目使用的代码。有下单,退款,查询退款,回调中验证签名的方法。其他api的调用可以依样画葫芦。最好把注释都看一下,因为有写本人在使用过程中遇到的一些坑。

    ZedGraph源文件及代码

    ZedGraph是个很好的C#画统计图插件,包括常见的柱状图,饼状图,折线图,能够弥补C#画统计...本资源包含了ZedGraph的C#源码,并有详细的画图demo,通过依样画葫芦就可以让开发人员快速地利用ZedGraph画出绚丽的统计图。

    Winform特效库MyAE

    你也可以在...我会把最近的更新放在上面。 你可以通过简单的一句代码设置各种各样的特效,例如设置Winform圆角,或者设置某个label动态显示时间,当然,你也可以依样画葫芦的添加自己的特效。

    JAVA8_API_SRC_SAMPLE.chm

    但对初学者来说,一般查API文档,可以知道每个类的结构及层次、基本作法,再依样画葫芦,是最基本的学习方法。但不能全方位地了解类库中某个类的真实全貌,不能说不是一个遗憾,毕竟能写类库的都是大师,能随时学习...

    flask_based_video_monitor.zip

    网站的框架是使用flask,这是一个轻量级的框架,操作简单,作为小白的我也不需要花费多大的时间就可以简单上手了,当然也只能依样画葫芦。 摄像头采用CSI接口摄像头,基本上不用USB摄像头,不懂树莓派为什么USB这么...

    基于BERT模型的中文文本情感二分类python源码+项目说明(期末大作业).zip

    在run_classsifier.py文件中我们可以看到,Google对于一些公开数据集已经写了一些Processor,如XnliProcessor,MnliProcessor,MrpcProcessor和ColaProcessor,因此对于自己的Processor依样画葫芦复制粘贴即可。...

    apollo-use-cases:展示Apollo配置中心的各种使用场景和示例代码,欢迎大家把日常工作中的更多配置使用案例分享出来!

    :演示如何通过Apollo配置中心实现动态切换数据源(其它类型的DataSource也是类似的,可以依样画葫芦) dubbo: 演示Dubbo如何通过Apollo配置中心实现中心化配置 spring-boot-dubbo: 演示Dubbo Spring Boot Starter...

    江苏省铜山区清华中学七年级语文下册 18 竹影学案(无答案) 新人教版

    - “依样画葫芦”指的是简单的模仿,缺乏创新和艺术感。 - “如此”指中国画的特点,不注重像不像,强调的是神似而非形似。 - 写“画竹”是为了深化主题,从实际的竹影到讨论画竹,揭示了艺术创作的过程和理念。 ...

    aspx实现的 jquery ui 的 flexgrid demo

    于是昨天开始慢慢深入研究flexgrid,但似乎找不到aspx的flexgrid demo,只有PHP、asp的一些demo,对于我这个对PHP的生手,实在是有点难度,于是今天依样画葫芦把PHP的一个flexgrid的demo做成了aspx的,或许其他的...

    Portapack应用开发教程(二)代码结构

    由于我要做的程序基本是replay改的,所以我只要找到replay程序所在的几个代码的目录,然后依样画葫芦,写一个类似的程序即可,除此之外还要把自己写的cpp文件加到相应的CMakeLists.txt里去就行了。 我看了一下几个...

    PT-all:常用PT一键脚本

    作者是个菜鸡,没学过程序,本脚本的不少内容是 依样画葫芦 + 抄袭 + 百度/谷歌得来的 建议重装完系统后安装本脚本,非全新安装的情况下翻车几率更高 本文内容不会及时更新;目前最新的脚本在界面上和截图里有一些不...

    安徽省临泉一中、灵璧中学2020学年高二语文下学期两校联考试题(含解析).doc

    然而,无论是哪种模仿,都陷入了“依样画葫芦”的误区,忽视了艺术创作中的创新和个性表达。 文章引用德拉克洛瓦的话,“自然只是一部字典而不是一部书”,强调了自然对艺术创作的启发性而非决定性作用。欣赏艺术时...

    广东省汕头市高三语文第二次模拟考试试题扫描版 试题.doc

    4. 语文阅读理解 - 推理判断: 题目中对文章段落的解析,如"导致画者因依样画葫芦而失去观察能力",这是对原文内容的推理,提醒考生在阅读理解中需准确把握作者意图,避免误解。 5. 文言文阅读 - 历史人物与事件: ...

    EssentialCpp

    将先前介绍的main()程序依样画葫芦地输入。 测试1.5 编写一个程序,能够查询用户的姓名,并读取用户所输入的内容。请确保用户输入的名称长度大于两个字符。如果用户的确输入了有效名称,就响应一些信息。请分别以C...

    CMMI三级项目经理关注过程域自我评估

    这就是我们常说的你是知其然并知其所以然,还是简单的依样画葫芦,最后大家可能都能够过CMMI三级,但是最终对项目,对我们软件产品的质量能够改进多少则可能不同项目差别很大.我会把这方面的一些实践和经验逐步的写出来...

    《读笑话学成语1》51-60.ppt

    “依样画葫芦”比喻单纯模仿,缺乏创新。这些成语可以帮助我们描述人物的行为和情绪,以及对事物的评价。 第54课的成语有“鬼斧神工”,形容工艺精巧,非人力所能及;“心旷神怡”表示心情舒畅,精神愉快;...

    初三语文秋期第一次月考试题.docx

    4. 成语运用部分测试学生能否恰当使用成语,如“依样画葫芦”表示模仿,但不创新,“流连往返”应改为“流连忘返”,表示对某地或某事物的喜爱不愿离去。 5. 试题还涉及到了文体知识,如议论文的构成、论证方法,...

Global site tag (gtag.js) - Google Analytics