在jasperreport中使用applet进行客户端打印以及jre在局域网中的自动安装

准备做一个基于jasperreport 的报表打印,之前实现了一版,调用的是服务器端的打印机,但是不太符合要求,准备改成applet方式,实现客户端本地打印。
我们的客户端软件用的是eclipse的插件开发。
所用的applet,使用的是jasperreport3.0的例子中的webapp。用ant编译后导出一个war包,然后放到tomcat下面即可运行。
我在运行例子的时候,我的ie不能显示,看了源码,例子中使用的是object标签,我把object标签删掉,用下面注掉的applet标签,可以正常使用。
下面把例子放到我自己的工程中,出现问题,在运行例子中的Servlet的时候,总是提不正常。先开始是提示jasperreport中使用的common-loggin和我工程中使用的log4j冲突,common-logging不能获取实例。在经历了换版本,jar包换位置(就是都放到tomcat的bin目录下去,删去工程目录中的。)等等,终于不报common-loggin的错了,又开始提示找不到jasperreport中的类,那个类明明在那里,而且是jasperreport运行到中间的时候的一个类,什么什么编译用的,具体名字忘了,所以肯定不是jasperreports-3.0.0-applet.jar的位置的问题。这个问题困扰我2天,然后有次无意中把Servlet换了个包。。好了。靠。。至今也不明白为什么。
下面给出部分主要代码:
applet代码就不贴了,基本上和例子中的一样,就是删去了一个按钮,并且去掉了打印机选择的那个对话框
servlet我没有用例子中的,而是改成了调用一个action,其实这里写什么都是一样的,因为在applet中主要是调用了jasperPrint = (JasperPrint)JRLoader.loadObject(url);这一句,这个url需要是一个装填好的jasperPrint,如果之前生成了这样的文件,那么哪怕直接写文件的地址都可以。
action中的主要代码是这样的。
PrintFromAppletAction.java
@Override public ActionForward ExecuteIt(FrameActionMapping mapping, FrameForm form, HttpServletRequest request, HttpServletResponse response, IActExcResult actExcResult)
throws IOException, ServletException { String cardid = request.getParameter("key_CARDID");
String showbackground="1"; // 构造传入报表的参数
HashMap param = new HashMap(); param.put("showbackground", showbackground);
// 获取数据库连接
Connection conn = null; try{
conn = DBConnectionMgr.getConnection(FrameConstant.MID_DATASOURCE_LEVEL); //构造查询sql
String sql="//一些sql,占地方,不写了"; //执行查询
DaoQryHelper objDaoQryHelper = DaoQryHelper.getInstance(); ArrayList spotList = objDaoQryHelper.getQueryStringList(conn,sql, null);
if (spotList != null && spotList.size() > 0) { spotList = (ArrayList) spotList.get(0);
if (spotList.size() > 0) { //将sql的查询结果put进param
} else { System.err.println("查询返回空:spotList.get(0)");
} } else {
System.err.println("查询返回空:spotList"); }
} catch (Throwable e) { e.printStackTrace();
request.getSession(true).setAttribute(Globals.ERROR_KEY, "查询数据库错误:<br>" + e.getMessage()); return mapping.findForward("error");
} finally { DBConnectionMgr.freeConn(conn);
}
String jasperFileName="prescription.jasper"; // 获取.jasper文件路径
EnsureFolderExist(getSysRootPath()+"reportCustomization"); String jasperFilePath = getSysRootPath()+"reportCustomization\\"+jasperFileName;
JasperPrint jasperPrint = null; try {
jasperPrint=JasperFillManager.fillReport(jasperFilePath, param, new JREmptyDataSource());//这句是关键,这句生成了这个jasperPrint就是要传给applet的。 } catch (JRException e) {
// TODO Auto-generated catch block e.printStackTrace();
return null; }
if (jasperPrint != null) {
response.setContentType("application/octet-stream"); ServletOutputStream ouputStream = response.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(ouputStream);
oos.writeObject(jasperPrint); oos.flush();
oos.close();
ouputStream.flush(); ouputStream.close();
} else
{ System.err.println("jasperPrint为空");
return null; }
return mapping.findForward(""); }
下面是页面的调用,是在一个jsp页面。<wbr style="LINE-HEIGHT: 1.3em">
<object classid = "clsid:CAFEEFAC-0015-0000-0000-ABCDEFFEDCBA"
codebase = "<%=request.getContextPath()%>/jre-1_5_0_16-windows-i586-p.exe" WIDTH = "80" HEIGHT = "35" >
<PARAM NAME = CODE VALUE = "PrinterApplet.class" > <PARAM NAME = CODEBASE VALUE = "applets" >
<PARAM NAME = ARCHIVE VALUE = "jasperreports-3.0.0-applet.jar" > <param name = "type" value = "application/x-java-applet;jpi-version=1.5">
<param name = "scriptable" value = "false"> <PARAM NAME = "REPORT_URL" VALUE ="../printFromAppletAction.do?key_CARDID=<%=printID%>">
<PARAM NAME = "SHOW_DIALOG" VALUE ="true">
<input type="button" value="服务器端打印" onclick="javascript:printPdf()">
</object></wbr><wbr style="LINE-HEIGHT: 1.3em"></wbr>
这个object标签大部分是转过来了,他的原型是这样的:<wbr style="LINE-HEIGHT: 1.3em">
<APPLET CODE = "PrinterApplet.class" JAVA_CODEBASE = "applets" ARCHIVE = "jasperreports-3.0.0-applet.jar" WIDTH = "80" HEIGHT = "35"> <PARAM NAME = "REPORT_URL" VALUE ="../printFromAppletAction.do?key_CARDID=<%=printID%>">
<PARAM NAME = "SHOW_DIALOG" VALUE ="true"></wbr><wbr style="LINE-HEIGHT: 1.3em"></wbr>
在jdk的bin目录中有一个叫做HtmlConverter.exe的工具,在cmd中输入HtmlConverter -gui可以打开图形界面。<wbr style="LINE-HEIGHT: 1.3em">
选择好目录以后按转换,就可以将applet标签变成object标签。</wbr><wbr style="LINE-HEIGHT: 1.3em">
applet标签是ie以前用的,现在applet的标准很混乱,而且applet标签功能也比较少,所以现在sun推荐大家使用object标签。</wbr><wbr style="LINE-HEIGHT: 1.3em">
object标签的好处是可以检查你有没有jre,没有的话可以给你下一个。</wbr><wbr style="LINE-HEIGHT: 1.3em">
关于object 的codebase和code,要和项目中的路径对应好,否则很容易出现找不到类的问题。</wbr><wbr style="LINE-HEIGHT: 1.3em">
其中,applet虽然是类,但是不要放在eclipse的src目录下面,也不要有任何包。</wbr><wbr style="LINE-HEIGHT: 1.3em">
对于我这个,我的applet放在了工程根目录下面的applets文件夹,applets在codebase中指明。</wbr><wbr style="LINE-HEIGHT: 1.3em">
ARCHIVE</wbr><wbr style="LINE-HEIGHT: 1.3em"> 是指运行这个applet需要的一些环境,我加载了jasperreports-3.0.0-applet.jar,<wbr style="LINE-HEIGHT: 1.3em">这个类可以在jasperreport的例子中找到。</wbr><wbr style="LINE-HEIGHT: 1.3em"></wbr></wbr><wbr style="LINE-HEIGHT: 1.3em">
jasperreports-3.0.0-applet.jar也被窝放到了applets文件夹下面。</wbr><wbr style="LINE-HEIGHT: 1.3em">
下面要说自动安装jre的问题。</wbr><wbr style="LINE-HEIGHT: 1.3em">
因为我的应用环境是一个小型局域网,并且部署环境有可能不能上外网,所以,我希望把jre放在局域网中的服务器上。</wbr><wbr style="LINE-HEIGHT: 1.3em">
用htmlconverter转换完以后的object的codebase本应是这样的:codebase="
http://java.sun.com/update/1.5.0/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0<wbr>"</wbr></wbr><wbr style="LINE-HEIGHT: 1.3em">
这是sun提供的一个cab包,里面有一个jinstall-1_5_0.inf和一个jinstall.exe。其中jinstall-1_5_0.inf是这样写的:</wbr><wbr style="LINE-HEIGHT: 1.3em">
</wbr>
; Version number and signature of INF file. ;
[version] signature="$CHICAGO$"
AdvancedINF=2.0
; The order of files in this section defines the download order. ; Last in First download.
[Add.Code] jinstall.exe
jpiexp32jpiexp32.dll=jpiexp32.dll npjpi150npjpi150.dll=npjpi150.dll
[jpiexp32.dll]
FileVersion=1,5,0,0 RegisterServer=no
clsid={8AD9C840-044E-11D1-B3E9-00805F499D93} hook=bridgeinstaller
[npjpi150.dll]
FileVersion=1,5,0,0 RegisterServer=no
clsid={CAFEEFAC-0015-0000-0000-ABCDEFFEDCBA} hook=bridgeinstaller
[jinstall.exe]
file-win32-x86=thiscab FileVersion=1,5,0,0
; jinstall.exe will be executed.
; [bridgeinstaller]
run=%EXTRACT_DIR%\jinstall.exe /installurl=http://java.sun.com/update/1.5.0/1.5.0-b64.xml
看到没,是用jinstall.exe 根据
http<wbr></wbr><wbr style="LINE-HEIGHT: 1.3em">
://java.sun.com/update/1.5.0/1.5.0-b64.xml<wbr style="LINE-HEIGHT: 1.3em"></wbr></wbr><wbr>这个xml文件去下载的。其中1.5.0-b64.xml这个xml文件中有这样一句:</wbr><wbr style="LINE-HEIGHT: 1.3em">
</wbr>
<title>Java 2 Runtime Environment, v1.5.0-b64</title> <description>This is 1.5.0-b64.</description>
<url>http://javadl.sun.com/webapps/download/GetFile/1.5.0-b64/windows-i586-jre/jre-1_5_0-windows-i586-iftw.exe</url>
按照里面的地址下载那个exe,发现并不是一个offline版本的,而是一个online版本的。也就是说,需要联网才能下载的。
至此,有2种方法可以实现在局域网内的jre自动安装,一种,是我上面用的,直接在object的codebase中写一个jre的exe文件,这个jre放在工程目录下面。这个jre可以从sun的官网上下载。
第二种,是把上述的cab啊,xml啊都下载下来,部署在工程中,但是,最后的xml中,还是要写完整的jre而不是原版中提供的online版的。
这里有点小问题,如果使用sun提供的方式也就是在线下载jre,下载安装完成之后,页面上直接就可以显示出applet来,但是如果使用我的方式,下载完成后就必须重启ie。
算是一点小的瑕疵吧。。不知道怎么才能做到和sun提供的那个一样。
以下,在ie6和ie7下测试正常,其中ie7有时候需要在高级中把jre应用于applet这个选项选中,并且在加载项中把sun控制台启用(据说默认是停用的)。
如果用遨游,需要在设置的高级中,选择使用其它jre。不然它默认使用的微软的jre。
我使用的环境,tomcat5,jasperreport3.0,ie7/6
关于java plugin 可以看http://java.sun.com/javase/6/webnotes/family-clsid.html。
里面介绍了objcet标签的clsid怎么写。
另外,网上看到很多人提到要数字签名,这个我不太懂,我没用,貌似也能正常使用,用了一下,好像也没什么反应。
怎么签名就不写了,也是用jdk的bin中的工具,(keytool),很简单。
感觉,用applet,真是一个过时的东西。慢的要死。还不好看。
相关推荐
在"jasperreport+applet客户端打印demo"中,我们探讨的是如何利用JasperReport结合Java Applet技术实现客户端的打印功能。 首先,JasperReport提供了丰富的模板设计功能,通过JRXML文件可以定义报告的布局、样式、...
在本主题中,我们将探讨如何利用JasperReport进行客户端打印,特别是通过Applet的方式。 首先,我们需要理解JasperReport的核心概念。JasperReport允许用户使用JRXML文件设计报告模板,这个模板包含了布局、数据源...
在Java Web Start或嵌入到HTML中的Applet中,我们可以加载JasperReport生成的报表,并通过Applet调用系统的打印服务,从而实现在客户端进行无服务器打印。然而,需要注意的是,由于安全限制和浏览器兼容性问题,Java...
客户端打印PDF以及服务器打印是Java开发中常见的需求,特别是当涉及到报表生成时,JasperReport是一个广泛使用的开源库。本文将深入探讨如何使用JasperReport进行客户端和服务器端的PDF打印。 首先,JasperReport是...
**JasperReport客户端打印...总之,JasperReport的客户端打印功能使得用户可以在本地环境中自由地管理和打印报表,提高了用户体验。通过熟练掌握相关API和技巧,开发者可以灵活地构建满足各种需求的报表打印解决方案。
在这个特定的话题中,我们关注的是JasperReports如何实现在Web环境下进行客户端打印。 在Web网页打印的场景下,用户通常希望能够在浏览器中直接预览并打印报表,而无需下载到本地后再进行操作。JasperReports 提供...
### iReport + JasperReport 客户端打印与数字签名详解 #### 一、概述 iReport 是一个用于设计 JasperReports 报告模板的图形界面工具,而 JasperReports 则是一款非常流行的 Java 报告工具,它能够从各种数据源...
标题中的“jasperreport生成pdf实现下载与打印”是指使用JasperReports库来创建PDF报告,并提供下载和打印功能。JasperReports是一个开源的Java报表工具,它允许开发者设计、生成和导出各种类型的报表,包括PDF、...
标题中的“jasperreport报表模板预览 applet与servlet通信”揭示了本文将要讨论的重点,即如何在Java环境中使用JasperReport库创建报表模板,并通过Applet和Servlet进行数据交互来实现预览功能。JasperReport是一个...
**JasperReport与Servlet在Web应用中的打印预览** JasperReport是一款强大的开源报表工具,它允许开发者在Java应用程序、Web应用甚至独立的Java应用程序中创建复杂的报告。Servlet是Java Web开发中的一个重要组件,...
JasperReport 打印 导出PDF XLS 这是我们公司架构师搭的一套架构,封装好了打印 导出功能,其他的报表只要实现这个机制就能完成功能了,该抽象的都抽象出来了,只有一个view.jsp页面。
在JasperReport中,我们可以使用Java API来实现后台打印,例如使用`JasperRunManager.runReportToPdfFile()`或`JasperPrintManager.print()`方法。这些方法可以接收JasperReport文件的路径、数据源以及打印设置等...
在安装 JasperReport Server 之前,需要先安装 Mysql 数据库。安装步骤如下: 1. 解压 Mysql 安装包:#tar zxvf mysql-5.0.18.tar.gz 2. 进入 Mysql 安装目录:#cd mysql-5.0.18 3. 配置 Mysql:#./configure --...
// 使用JasperReport进行打印 JRPrintServiceExporter exporter = new JRPrintServiceExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter...
标题“jasperReport+struts2+jatoolsPrinter打印”涉及的是一个集成开发场景,主要集中在Java企业级应用中的报表生成和打印功能。jasperReport是一个强大的开源报表工具,能够帮助开发者创建复杂的报告设计;Struts2...
jasperReport5.6.1编码以及使用 JasperReport是一款功能强大的报表生成工具,广泛应用于各种Java应用程序中。下面是关于JasperReport5.6.1编码以及使用的详细知识点。 JasperReport编码 JasperReport编码是指在...
### JasperReport中使用多个数据源的方法详解 #### 场景背景 在报表开发过程中,有时我们需要在一个报表中展示不同来源的数据。例如,在同一份报告中同时呈现交叉表和饼状图,而这两部分数据可能源自不同的数据库表...
安装JasperReport需要首先下载JasperReport的安装包,然后按照安装向导进行安装。安装完成后,需要配置JasperReport的环境变量。 ### iReport的安装与配置 iReport需要JasperReport和JDK来运行。安装iReport需要...