ireport5.6.0+jasperreports-5.6.0+applet實現客戶端列印
我也是第一次使用ireport這個報表工具。在網上找了各種資料,最終實現了列印功能,當把程式部署到伺服器上才知道,並不能實現客戶端列印。後來繼續百度,找到了可以通過applet實現客戶端列印的方法,也找到了很多列子,跟著敲了一邊,因為使用的jasperreports的版本不一致,所以也遇到了各種問題。
我最開始做列印參考http://aijnecjay.iteye.com/blog/1689372 這裡寫的,因為版本不一致,在瀏覽器上不能彈出列印提示。
最終檢視java控制檯,才知道缺少什麼jar包,缺什麼就加什麼,一步一步完善。先說下需要用到的jar包,下載連結
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是否編寫成功,若成功,瀏覽器會彈出 下載提示
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 成功則會彈出下面的彈窗。
接下來修改 printApplet
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已經包含這個包了。
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列印已經做好了。有不足的地方歡迎大家指正。