最近因为项目需要,要在applet上显示报表,一下子傻了眼,applet已经N年没用过了,上网找了好久,找到了JasperReport-applet.以下就来说说如何在applet上显示报表.
首先需要下载jasperReport的jar包.可以去他的官网上下.目前最新版本为2.0.5.
新建工程,在WebRoot下新建文件夹applets,当然这名字随意建.不过后面有配置地方需要用的到.在jasperreport包内demo/samples/webapp/applets下,把EmbeddedViewerApplet.class,JRViewerSimple.class,以及jasperreport-2.0.5-applet.jar拷入自己项目中建的applets文件夹下.注意,刚打开那个jar包里是没有class文件,只有java文件,需要用ant build下.你也可以拷出java文件,然后编译.
OK,以上一些基本操作已经完成.下面就要一些编程操作了.
写个处理的servlet, 代码如下:
PdfViaAppletServlet,
public class PdfViaAppletServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
ServletContext context = this.getServletConfig().getServletContext();
if (request.getSession().getAttribute(MyDataSource.REPORT_DATASOURCE) == null)
{
showNoData(response);
return;
}
MyDataSource myDataSource = (MyDataSource) request.getSession()
.getAttribute(MyDataSource.REPORT_DATASOURCE);
File reportFile = new File(context.getRealPath("/WEB-INF/reports/"
+ myDataSource.getFilename() + ".jasper"));
if (!reportFile.exists())
throw new JRRuntimeException(
"File "
+ myDataSource.getFilename()
+ ".jasper not found. The report design must be compiled first.");
myDataSource.getParameters().put("BaseDir", reportFile.getParentFile());
if (myDataSource.getFields() == null || myDataSource.getFields().size() == 0)
{
showNoData(response);
return;
}
// byte[] bytes = null;
JasperPrint jasperPrint = null;
try
{
// log.debug(" ===== start to generate pdf file ===== ");
// bytes = JasperRunManager.runReportToPdf(reportFile.getPath(),
// myDataSource.getParameters(), myDataSource);
jasperPrint = JasperFillManager.
fillReport(reportFile.getPath(), myDataSource.getParameters(), myDataSource);
// log.debug(" ===== end to generate pdf file ===== ");
}
catch (JRException e)
{
showException(response, e);
return;
}
if (jasperPrint != null)
{
response.setContentType("application/octet-stream");
// response.setContentLength(bytes.length);
ServletOutputStream outputStream = response.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
// outputStream.write(bytes, 0, bytes.length);
oos.writeObject(jasperPrint);
oos.flush();
oos.close();
outputStream.flush();
outputStream.close();
request.getSession()
.removeAttribute(MyDataSource.REPORT_DATASOURCE);
}
else
{
showNoData(response);
}
}
//--------- private method --------------
private void showException(HttpServletResponse response, JRException e)
throws IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>InHouse2 - Reports</title>");
out
.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"/styles/default.css\"");
out.println("</head>");
out.println("<body>");
out
.println("<span class=\"bnew\">InHouse2Report encountered this error :</span>");
out.println("<pre>");
e.printStackTrace(out);
out.println("</pre>");
out.println("</body>");
out.println("</html>");
}
private void showNoData(HttpServletResponse response) throws IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>InHouse2 - Reports</title>");
out
.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"/styles/default.css\"");
out.println("</head>");
out.println("<body>");
out.println("No data show");
out.println("</body>");
out.println("</html>");
}
}
OK,基本上快完成了,上面的MyDataSource是自己定义,代码如下:
MyDataSource,
public class MyDataSource implements JRDataSource {
public final static String REPORT_DATASOURCE = "report_datasource";
private int index = -1;
private String filename;
private Map parameters;
private List fields;
public MyDataSource(String filename, Map parameters, List fields) {
this.parameters = parameters;
this.fields = fields;
this.filename = filename;
}
public boolean next() throws JRException {
index++;
return (index < fields.size());
}
public Object getFieldValue(JRField field) throws JRException {
Map record = (Map) fields.get(index);
return record.get(field.getName());
}
public Map getParameters() {
return parameters;
}
public String getFilename() {
return filename;
}
public List getFields() {
return fields;
}
}
最后就是显示的页面了:当然这里applet标签需要用object标签替换:
view.html,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>view.html</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
</head>
<body>
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 100% HEIGHT = "100%" codebase="http://java.sun.com/update/1.4.2/jinstall-1_4-windows-i586.cab#Version=1,4,0,0">
<PARAM NAME = CODE VALUE = "EmbeddedViewerApplet.class" >
<PARAM NAME = CODEBASE VALUE = "applets" >
<PARAM NAME = ARCHIVE VALUE = "jasperreports-2.0.5-applet.jar,jasperreports-2.0.5.jar" >
<PARAM NAME = "type" VALUE ="application/x-java-applet;version=1.2.2">
<PARAM NAME = "scriptable" VALUE ="false">
<PARAM NAME = "REPORT_URL" VALUE ="../PdfViaAppletServlet">
<COMMENT>
<EMBED
type = "application/x-java-applet;version=1.4"
CODE = "EmbeddedViewerApplet.class"
CODEBASE = "applets"
ARCHIVE = "jasperreports-2.0.5-applet.jar,jasperreports-2.0.5.jar"
scriptable = "false"
REPORT_URL = "../PdfViaAppletServlet"
pluginspage = "http://java.sun.com/products/plugin/index.html#download" width="100%" height="100%">
<NOEMBED>
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
Your browser is completely ignoring the <APPLET> tag!
</NOEMBED>
</EMBED>
</COMMENT>
</OBJECT>
</body>
</html>
大致流程在后台得到MyDataSource,放入session.跳转至view.html.出报表.至于一些细节方面,如果有看不懂的地方可以问我.
备注:关于放入applets文件夹内的2个class最好不要有package.如果有的话路径方面有的小麻烦,经常会报找不到某某类.