天天看点

ireport5.6.0+jasperreports-5.6.0+applet实现客户端打印

       我也是第一次使用ireport这个报表工具。在网上找了各种资料,最终实现了打印功能,当把程序部署到服务器上才知道,并不能实现客户端打印。后来继续百度,找到了可以通过applet实现客户端打印的方法,也找到了很多列子,跟着敲了一边,因为使用的jasperreports的版本不一致,所以也遇到了各种问题。

       我最开始做打印参考http://aijnecjay.iteye.com/blog/1689372 这里写的,因为版本不一致,在浏览器上不能弹出打印提示。

最终查看java控制台,才知道缺少什么jar包,缺什么就加什么,一步一步完善。先说下需要用到的jar包,下载链接https://download.csdn.net/download/wlj_wangjun/10579753

     1. 先写Servlet

package com.tianjian.report.applet;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tianjian.report.util.DBUtil;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;

public class printServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;  
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response){
        ServletContext context = request.getSession().getServletContext();
        String filepath=context.getRealPath("ireport/entryExamination/Onboarding.jasper");
        
            try {
                    //这里因为需要实现批量打印,所以使用list ,将所有需要 JasperPrint 装在list中
                    List<JasperPrint> list = new ArrayList();
            
                    Map<String,Object> map = new HashMap();
                    map.put("peId", "100");
                    map.put("peVisitId", "6");
                    
                    JasperPrint jasperPrint = JasperFillManager.fillReport(filepath,map, DBUtil.getConnection());
                    list.add(jasperPrint);
            
                response.setContentType("application/octet-stream");   
                ServletOutputStream ouputStream = response.getOutputStream();   
                ObjectOutputStream oos = new ObjectOutputStream(ouputStream);   
                oos.writeObject(list);//将所有JasperPrint对象写入对象输出流中   
                oos.flush();   
                oos.close(); 
                    
            } catch (JRException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                } 
    }  
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response){ 
    }          
}
           

2.在web.xml中配置servlet

<servlet>  
      <servlet-name>printServlet</servlet-name>  
      <servlet-class>com.tianjian.report.applet.printServlet</servlet-class>  
  </servlet>  
  <servlet-mapping>  
      <servlet-name>printServlet</servlet-name>  
      <url-pattern>/printServlet</url-pattern>  
  </servlet-mapping>
           

在浏览器中输入 http://localhost:8080/report/printServlet 测试servlet是否编写成功,若成功,浏览器会弹出 下载提示

ireport5.6.0+jasperreports-5.6.0+applet实现客户端打印

3.新建一个applet类

package com.tianjian.report.applet;

import java.applet.Applet;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.util.List;

import javax.swing.JOptionPane;

import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.util.JRLoader;

public class printApplet extends Applet {

    private static final long serialVersionUID = 1L;  
    private URL url=null;  
  
    public printApplet() {  
        
    }  
  
    @SuppressWarnings("unused")
    public void init() {  
        String strUrl = "http://localhost:8080/report/printServlet"; 
          //String strUrl =getParameter("REPORT_URL");
        if (strUrl != null) {  
            try {  
                url = new URL("http://localhost:8080/report/printServlet");
                //url = new URL(getCodeBase(),strUrl); 
              } catch (Exception e) {  
                    StringWriter swriter = new StringWriter();    
                    PrintWriter pwriter = new PrintWriter(swriter);    
                    e.printStackTrace(pwriter);  
                    JOptionPane.showMessageDialog(this, swriter.toString());    
            }
            
        } else {  
            JOptionPane.showMessageDialog(this, "Source URL not specified");  
        }  
    }  
  
    public void start() {  
        System.out.println("..........................start()");
        if (url != null) {  
            try {  
                //JasperPrint obj = (JasperPrint)JRLoader.loadObject(url);
                List<JasperPrint> list = (List<JasperPrint>) JRLoader.loadObject(url);
                System.out.println(list.size());
                for(int i=0;i<list.size();i++){
                    
                    JasperPrintManager.printReport(list.get(i), true); //true:弹出打印机窗口,false不弹出打印机窗口
                }
                //JasperPrintManager.printReport(obj, true);
            } catch (Exception e) {  
                e.printStackTrace();   
            }  
        } else {  
            JOptionPane.showMessageDialog(this, "start():Source URL not specified");  
        }  
    }  
}
           

可以右键 Run as -> java Applet  成功则会弹出下面的弹窗。

ireport5.6.0+jasperreports-5.6.0+applet实现客户端打印

接下来修改 printApplet

ireport5.6.0+jasperreports-5.6.0+applet实现客户端打印

4.取出printApplet的class文件,包也带上。我的是 com.tianjian.report.applet 。

在本地新建一个文件print。

把 com/tianjian/report/applet/printApplet.class 文件夹和文件一起放进来。

然后把 jasperreports-applet-5.6.0.jar 解压后的文件全部放入print文件夹内。

使用命令的方式将这个 print文件夹重新打成jar包。

在print文件夹内的地址栏输入 cmd,

输入 jar cvf print.jar *   文件夹内就会有一个print.jar。

现在给print.jar包签名 以下操作都是在命令窗口执行。

(一).keytool生成证书:keytool -genkey -alias printkey -keystore printstore -validity 3650     (注意:-validity 3650 标识证书的有效期是10年,如果不写,默认是3个月。)

(二).keytool导出证书:keytool -export -keystore printstore -alias printkey  -file print.cer      (需要输入一些信息,我随便填写的,会在print文件夹内生成一个print.cer的文件,这个文件名字可以随意取。)

(三).用jarsigner给jar包签名 :   jarsigner -keystore printstore print.jar printkey 

(jasperreports-5.6.0.jar也要签名,现在把这个包放到print文件内,在执行一遍 jarsigner -keystore printstore jasperreports-5.6.0.jar printkey) 不是 这个 jasperreports-applet-5.6.0.jar,看仔细了。

5.  在webapp目录下新建一个文件夹 叫applet,(我的项目是maven项目,所以有webapp文件夹,普通项目就是webRoot文件夹了)

把所需的jar包 和 刚才签名的jar包,还有print.cer文件放进来。jasperreports-applet-5.6.0.jar这个包可以不要了,因为print.jar已经包含这个包了。

ireport5.6.0+jasperreports-5.6.0+applet实现客户端打印

6.安装jre_1.8_0_181版本,因为这个版本不会在浏览器上频繁的弹出安全提示。下载地址:java.com

安装完成之后,

在控制面板中 点击java  会弹出一个java控制面板,选择 java- 点击查看 里面有个列表,把刚才安装的jre添加进去,勾选,确定。

在 java控制面板中 点击 安全 - 里面有一个"例外站点列表",为了简单,将我们的项目访问路径 添加进去例如:localhost:8080/   ; 就把 以localhost:8080/..... 开头的所有url都设置成例外站点。 点击应用--确定。

设置ie浏览器,我的是iE11,打开internet选项,

选择安全,选择-受信任的站点,-点击 站点-将 http://localhost:8080/地址添加进去,把下面的对该区域中的所有站点要求服务器验证(https:)选项去掉。关闭

7.以上都准备好 以后,在jsp中写个方法

function print(){

var print = document.getElementById("print");
var url="printServlet";

var appletStr='<APPLET ID="JrPrt" CODE="com.tianjian.report.applet.printApplet.class" CODEBASE = "./" ARCHIVE = "applet/xerces-2.9.0.jar, applet/batik-all-1.5.1.jar,applet/batik-dom-1.6-1.jar,applet/batik-svg-dom-1.6-1.jar,applet/commons-digester-2.1.jar,applet/batik-1.1.1.jar,applet/batik-bridge-1.6-1.jar,applet/jasperreports-5.6.0.jar,applet/print.jar,applet/commons-logging-1.1.1.jar,applet/commons-collections-3.2.1.jar" WIDTH = "0" HEIGHT = "0"><PARAM NAME = "type" VALUE="application/x-java-applet;version=1.2.2"><PARAM NAME = "scriptable" VALUE="false"><PARAM NAME = "REPORT_URL" VALUE ="'+url+'"></APPLET>';


print.innerHTML = appletStr;

}
           

写个onclick事件,调用print方法。成功后会弹出打印机选项窗口。至此 一个applet打印已经做好了。有不足的地方欢迎大家指正。