手把手教你用Java制作原生态的报表

来源:互联网 发布:尔雅网络课答案 编辑:程序博客网 时间:2024/04/27 15:54

今天下午没事干。主要是论文没有什么进展,唉!读研苦逼啊。突然想玩玩其他的,记得上次用JSP和Servlet是几个月前的事了。于是就任性的玩一回报表。

首先我是默认你不是菜鸟了,而且用过JSP和Servlet,会Java Web的基础知识,会使用Jdbc连接数据库。这些都是必要的知识,否则接下来的内容将没法讲解。

一、报表生成的关键要素

1、后台数据的抽取

2、数据项的逻辑运算

3、前台使用表格展示


二、使用流程图的形式展示3大关键要素

1、后台数据的抽取流程


我们来谈谈这个流程所需要的技术。

获取报表参数:主要是前台向后台进行传参,注意不能丢参数。

数据库的连接:JDBC连接数据库

合成SQL语句:标准的SQL语句、字符串的拼接

执行SQL语句:Java是如何操作数据库的

获取结果集:对结果集进行处理,这里将使用Java中的容器来存储数据

返回结果集:向Servlet进行传参

2、数据项的逻辑运算流程


我们来谈谈这个流程所需要的技术。

获得数据库的原始数据集:向Servlet中取值。

进行数据的运算转换:常用的加减乘除等运算函数。

重新组装数据:需要针对合适的数据格式,来选择合适的容器。

返回逻辑数据集:向前台页面传参。

3、前台使用表格展示流程


我们来谈谈这个流程所需要的技术。

获取逻辑数据集:Servlet的取值。

设置表格的样式:Html、Css、Js等技术。

遍历数据项:Js、AJax。


三、制作报表的准备工作。

首先你要在自己的电脑上安装Tomcat服务器。怎么安装,这个大家自己Google教程。接着需要自己的电脑上安装MyEclipse,这是Java Web开发的必备IDE。好了,然后你需要一个数据库(Mysql或者Oracle都行)能够为你提供你想要的数据。

这里介绍一下我要做的报表:

我是将学校数据库中记录变电所的实时电压数据(好吧,这是学校的一个节能平台的项目。),上传在前台的页面中显示。

数据库的数据展示,使用的是Oracle数据库。

首先是数据库的信息:包含数据库名、SID、以及IP地址、用户名、密码、端口号


数据库待查询的表的信息:这里查询的是TB_TRANS_COLLECTION表的信息。我会将BK,UA,UB,UC这几个字段的记录全部显示到前台的页面上。


表中具体的记录值:



四、代码实现我的报表

首先我想给大家看一下我的项目大致文件的结构:


这里面我实际上是使用了一个最原始的MVC模型。Model模型层使用了beans文件下的Trans.java来表示的,View视图层使用index.jsp来完成的,Controller控制层

是servlet文件下的ShowReport.java文件。jdbc文件用来进行数据库的连接,而service文件是逻辑层,主要进行业务逻辑的处理。

第一步是完成model层的代码:

[java] view plain copy
print?
  1. package beans;  
  2. //这是建立数据模型  
  3. public class Trans {  
  4.     //板卡的序号  
  5.     private String bk;  
  6.     //三相电压的值  
  7.     private double ua;  
  8.     private double ub;  
  9.     private double uc;  
  10.     //三相电流的值  
  11.     private double ia;  
  12.     private double ib;  
  13.     private double ic;  
  14.     public String getBk() {  
  15.         return bk;  
  16.     }  
  17.     public void setBk(String bk) {  
  18.         this.bk = bk;  
  19.     }  
  20.     public double getUa() {  
  21.         return ua;  
  22.     }  
  23.     public void setUa(double ua) {  
  24.         this.ua = ua;  
  25.     }  
  26.     public double getUb() {  
  27.         return ub;  
  28.     }  
  29.     public void setUb(double ub) {  
  30.         this.ub = ub;  
  31.     }  
  32.     public double getUc() {  
  33.         return uc;  
  34.     }  
  35.     public void setUc(double uc) {  
  36.         this.uc = uc;  
  37.     }  
  38.     public double getIa() {  
  39.         return ia;  
  40.     }  
  41.     public void setIa(double ia) {  
  42.         this.ia = ia;  
  43.     }  
  44.     public double getIb() {  
  45.         return ib;  
  46.     }  
  47.     public void setIb(double ib) {  
  48.         this.ib = ib;  
  49.     }  
  50.     public double getIc() {  
  51.         return ic;  
  52.     }  
  53.     public void setIc(double ic) {  
  54.         this.ic = ic;  
  55.     }  
  56.       
  57. }  
package beans;//这是建立数据模型public class Trans {    //板卡的序号    private String bk;    //三相电压的值    private double ua;    private double ub;    private double uc;    //三相电流的值    private double ia;    private double ib;    private double ic;    public String getBk() {        return bk;    }    public void setBk(String bk) {        this.bk = bk;    }    public double getUa() {        return ua;    }    public void setUa(double ua) {        this.ua = ua;    }    public double getUb() {        return ub;    }    public void setUb(double ub) {        this.ub = ub;    }    public double getUc() {        return uc;    }    public void setUc(double uc) {        this.uc = uc;    }    public double getIa() {        return ia;    }    public void setIa(double ia) {        this.ia = ia;    }    public double getIb() {        return ib;    }    public void setIb(double ib) {        this.ib = ib;    }    public double getIc() {        return ic;    }    public void setIc(double ic) {        this.ic = ic;    }}

第二步,是完成数据库的连接操作,并在方法中返回数据库的连接。

[java] view plain copy
print?
  1. package jdbc;  
  2. import java.sql.*;  
  3. public class JdbcConn {  
  4.     //设置连接数据库的路径,包括IP地址、端口号、数据库的SID  
  5.     private  static String url=“jdbc:oracle:thin:@172.16.254.185:1521:AHUSERVICE”;  
  6.     //数据库的用户名和密码  
  7.     private static String user=“CS2013”;  
  8.     private static String password=“m123”;  
  9.     //建立一个数据库的连接  
  10.     public static Connection conn;//与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。  
  11.     public static PreparedStatement ps;  
  12.     public static ResultSet rs;///表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。  
  13.     public static Statement st;//用于执行静态 SQL 语句并返回它所生成结果的对象。  
  14.       
  15.     //创建一个连接数据库的方法  
  16.     public static Connection getConnection(){  
  17.         try {  
  18.             Class.forName(”oracle.jdbc.driver.OracleDriver”);//加载数据库的驱动  
  19.             conn=DriverManager.getConnection(url,user,password);//连接数据库  
  20.         } catch (Exception e) {  
  21.             // TODO Auto-generated catch block  
  22.             e.printStackTrace();  
  23.         }  
  24.           
  25.         return conn;  
  26.     }  
  27. }  
package jdbc;import java.sql.*;public class JdbcConn {    //设置连接数据库的路径,包括IP地址、端口号、数据库的SID    private  static String url="jdbc:oracle:thin:@172.16.254.185:1521:AHUSERVICE";    //数据库的用户名和密码    private static String user="CS2013";    private static String password="m123";    //建立一个数据库的连接    public static Connection conn;//与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果。    public static PreparedStatement ps;    public static ResultSet rs;///表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。    public static Statement st;//用于执行静态 SQL 语句并返回它所生成结果的对象。    //创建一个连接数据库的方法    public static Connection getConnection(){        try {            Class.forName("oracle.jdbc.driver.OracleDriver");//加载数据库的驱动            conn=DriverManager.getConnection(url,user,password);//连接数据库        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return conn;    }}

第三步,实现业务逻辑层的设计。

[java] view plain copy
print?
  1. package service;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.ResultSet;  
  5. import java.sql.SQLException;  
  6. import java.sql.Statement;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import beans.Trans;  
  11.   
  12. import jdbc.JdbcConn;  
  13.   
  14. public class Services {  
  15.     private Connection dbconnection;//数据库的连接  
  16.     private Statement st;//执行sql语句  
  17.     private ResultSet rs;//用于存放数据的容器  
  18.     private String sql;//用来存放要执行的数据库的语句  
  19.     private List list;//List容器是用来存储从数据库中返回的数据集  
  20.     private Trans ts;//定义一个模型对象  
  21.     public List getTrans(){  
  22.         list=new ArrayList();//初始化容器  
  23.         //获得数据库的连接  
  24.         dbconnection=JdbcConn.getConnection();  
  25.         //合成SQL语句和执行Sql语句  
  26.         try {  
  27.             st=(Statement)dbconnection.createStatement();//生成一个 <span style=”font-family: Arial, Helvetica, sans-serif;”>用于执行静态 SQL 语句并返回它所生成结果的对象</span>  
  28. <span style=”white-space:pre”>            </span>//已经确定好的sql语句  
  29.             sql=”select tb_trans_collection.bk bk,tb_trans_collection.ua ua,”+   
  30.                     ”tb_trans_collection.ub ub,tb_trans_collection.uc uc from ”+  
  31.                     ”tb_trans_collection order by  tb_trans_collection.bk”;  
  32.             rs=st.executeQuery(sql);//执行sql语句,并将结果保存在ResultSet的对象中  
  33.             //遍历rs中的元素,必需将ResultSet里的元素转化为Trans对象。  
  34.             while(rs.next()){  
  35.                 ts=new Trans();//注意每一次必须要new一个Trans对象  
  36.                 //依次设置值  
  37.                 ts.setBk(rs.getString(”bk”));  
  38.                 ts.setUa(rs.getDouble(”ua”));  
  39.                 ts.setUb(rs.getDouble(”ub”));  
  40.                 ts.setUc(rs.getDouble(”uc”));  
  41.                   
  42.                 list.add(ts);//向list容器中添加元素  
  43.             }  
  44.         } catch (SQLException e) {  
  45.             // TODO Auto-generated catch block  
  46.             e.printStackTrace();  
  47.         }  
  48.         return list;//返回list容器  
  49.     }  
  50.       
  51. }  
package service;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.List;import beans.Trans;import jdbc.JdbcConn;public class Services {    private Connection dbconnection;//数据库的连接    private Statement st;//执行sql语句    private ResultSet rs;//用于存放数据的容器    private String sql;//用来存放要执行的数据库的语句    private List list;//List容器是用来存储从数据库中返回的数据集    private Trans ts;//定义一个模型对象    public List getTrans(){        list=new ArrayList();//初始化容器        //获得数据库的连接        dbconnection=JdbcConn.getConnection();        //合成SQL语句和执行Sql语句        try {            st=(Statement)dbconnection.createStatement();//生成一个 <span style="font-family: Arial, Helvetica, sans-serif;">用于执行静态 SQL 语句并返回它所生成结果的对象</span><span style="white-space:pre">            </span>//已经确定好的sql语句            sql="select tb_trans_collection.bk bk,tb_trans_collection.ua ua,"+                     "tb_trans_collection.ub ub,tb_trans_collection.uc uc from "+                    "tb_trans_collection order by  tb_trans_collection.bk";            rs=st.executeQuery(sql);//执行sql语句,并将结果保存在ResultSet的对象中            //遍历rs中的元素,必需将ResultSet里的元素转化为Trans对象。            while(rs.next()){                ts=new Trans();//注意每一次必须要new一个Trans对象                //依次设置值                ts.setBk(rs.getString("bk"));                ts.setUa(rs.getDouble("ua"));                ts.setUb(rs.getDouble("ub"));                ts.setUc(rs.getDouble("uc"));                list.add(ts);//向list容器中添加元素            }        } catch (SQLException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return list;//返回list容器    }}

第四步,是实现我们的Controller层的内容。这里是编写一个Servlet。

[java] view plain copy
print?
  1. package servlet;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.List;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11. import service.Services;  
  12. public class ShowReport extends HttpServlet {  
  13.   
  14.     /** 
  15.      * Constructor of the object. 
  16.      */  
  17.     public ShowReport() {  
  18.         super();  
  19.     }  
  20.   
  21.     /** 
  22.      * Destruction of the servlet. <br> 
  23.      */  
  24.     public void destroy() {  
  25.         super.destroy(); // Just puts “destroy” string in log  
  26.         // Put your code here  
  27.     }  
  28.   
  29.     /** 
  30.      * The doGet method of the servlet. <br> 
  31.      * 
  32.      * This method is called when a form has its tag value method equals to get. 
  33.      *  
  34.      * @param request the request send by the client to the server 
  35.      * @param response the response send by the server to the client 
  36.      * @throws ServletException if an error occurred 
  37.      * @throws IOException if an error occurred 
  38.      */  
  39.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  40.             throws ServletException, IOException {  
  41.   
  42.         this.doPost(request, response);  
  43.     }  
  44.   
  45.     /** 
  46.      * The doPost method of the servlet. <br> 
  47.      * 
  48.      * This method is called when a form has its tag value method equals to post. 
  49.      *  
  50.      * @param request the request send by the client to the server 
  51.      * @param response the response send by the server to the client 
  52.      * @throws ServletException if an error occurred 
  53.      * @throws IOException if an error occurred 
  54.      */  
  55.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  56.             throws ServletException, IOException {  
package servlet;import java.io.IOException;import java.io.PrintWriter;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import service.Services;public class ShowReport extends HttpServlet {    /**     * Constructor of the object.     */    public ShowReport() {        super();    }    /**     * Destruction of the servlet. <br>     */    public void destroy() {        super.destroy(); // Just puts "destroy" string in log        // Put your code here    }    /**     * The doGet method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to get.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doPost(request, response);    }    /**     * The doPost method of the servlet. <br>     *     * This method is called when a form has its tag value method equals to post.     *      * @param request the request send by the client to the server     * @param response the response send by the server to the client     * @throws ServletException if an error occurred     * @throws IOException if an error occurred     */    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {
[java] view plain copy
print?
  1. <span style=“white-space:pre”>        </span>//这里添加自己的代码  
  2.         List list;//定义一个容器用来存储后台传来的数据集  
  3.         //声明一个service  
  4.         Services services=new Services();  
  5.         list=services.getTrans();//获取后台出入的数据容器  
  6.         if(list!=null){  
  7.             //将数据传入到前台,这里使用的是Session对象。我们使用Session来进行数据的  
  8.             request.getSession().setAttribute(”TRANS”, list);  
  9.             response.sendRedirect(”../index.jsp”);//请求重定向,相当于客户端的二次请求  
  10.         }  
  11.           
  12.     }  
  13.   
  14.     /** 
  15.      * Initialization of the servlet. <br> 
  16.      * 
  17.      * @throws ServletException if an error occurs 
  18.      */  
  19.     public void init() throws ServletException {  
  20.         // Put your code here  
  21.     }  
  22.   
  23. }  
<span style="white-space:pre">        </span>//这里添加自己的代码        List list;//定义一个容器用来存储后台传来的数据集        //声明一个service        Services services=new Services();        list=services.getTrans();//获取后台出入的数据容器        if(list!=null){            //将数据传入到前台,这里使用的是Session对象。我们使用Session来进行数据的            request.getSession().setAttribute("TRANS", list);            response.sendRedirect("../index.jsp");//请求重定向,相当于客户端的二次请求        }    }    /**     * Initialization of the servlet. <br>     *     * @throws ServletException if an error occurs     */    public void init() throws ServletException {        // Put your code here    }}

最后一步,进行前台页面的设计。这里需要将后台数据给显示出来。

[html] view plain copy
print?
  1. <!–首先要记得将需要的类包导进来–>  
<!--首先要记得将需要的类包导进来-->
[html] view plain copy
print?
  1. <%@ page language=“java” import=“java.util.*,beans.*” pageEncoding=“UTF-8”%>  
  2. <%  
  3. String path = request.getContextPath();  
  4. String basePath = request.getScheme()+”://”+request.getServerName()+”:”+request.getServerPort()+path+”/”;  
  5. %>  
  6.   
  7. <!DOCTYPE HTML PUBLIC ”-//W3C//DTD HTML 4.01 Transitional//EN”>  
  8. <html>  
  9.   <head>  
  10.     <base href=“<%=basePath%>”>  
  11.       
  12.     <title>JAVA环境生成报表</title>  
  13.     <meta http-equiv=“pragma” content=“no-cache”>  
  14.     <meta http-equiv=“cache-control” content=“no-cache”>  
  15.     <meta http-equiv=“expires” content=“0”>      
  16.     <meta http-equiv=“keywords” content=“keyword1,keyword2,keyword3”>  
  17.     <meta http-equiv=“description” content=“This is my page”>  
  18.     <!– 
  19.     <link rel=”stylesheet” type=”text/css” href=”styles.css”> 
  20.     –>  
  21.   </head>  
  22.     
  23.   <body>  
  24.     <form action=“servlet/ShowReport” method=“post”><!–假定是使用表单的形式来完成请求的–>  
  25.         <input type=“submit” value=“生成报表”>  
  26.     </form>  
  27.     <table>  
  28.       <tr>  
  29.         <th colspan=5>变电所三相电压信息</th>  
  30.       </tr>  
  31.       <tr>  
  32.         <th>序号</th>  
  33.         <th>板卡号</th>  
  34.         <th>A相电压</th>  
  35.         <th>B相电压</th>  
  36.         <th>C相电压</th>  
  37.       </tr>  
  38.     <%  
  39.         List list=null;//这里定义一个容器,用来存储数据  
  40.         if(session.getAttribute(“TRANS”)!=null){//判断Servlet是否通过Session来进行传值  
  41.             list=(List)session.getAttribute(“TRANS”);  
  42.             if(list.size()>0){  
  43.                 int id=0;//表示序号  
  44.                 Trans ts;//记得要引入类包  
  45.                 for(int i=0;i<list.size();i++){//依次遍历容器中的元素  
  46.                     ts=new Trans();  
  47.                     ts=(Trans)list.get(i);  
  48.                       
  49.                     %>  
  50.                      <tr>  
  51.                         <th><%=id+=1 %></th><!–获取容器元素的属性值–>  
  52.                         <th><%=ts.getBk() %></th>  
  53.                     <th><%=ts.getUa() %></th>  
  54.                         <th><%=ts.getUb() %></th>  
  55.                         <th><%=ts.getUc() %></th>  
  56.                     </tr>  
  57.                     <%   
  58.                 }  
  59.             }  
  60.         }  
  61.     %>  
  62.     </table>  
  63.   </body>  
  64. </html>  
<%@ page language="java" import="java.util.*,beans.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">    <title>JAVA环境生成报表</title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    <meta http-equiv="description" content="This is my page">    <!--    <link rel="stylesheet" type="text/css" href="styles.css">    -->  </head>  <body>    <form action="servlet/ShowReport" method="post"><!--假定是使用表单的形式来完成请求的-->        <input type="submit" value="生成报表">    </form>    <table>      <tr>        <th colspan=5>变电所三相电压信息</th>      </tr>      <tr>        <th>序号</th>        <th>板卡号</th>        <th>A相电压</th>        <th>B相电压</th>        <th>C相电压</th>      </tr>    <%        List list=null;//这里定义一个容器,用来存储数据        if(session.getAttribute("TRANS")!=null){//判断Servlet是否通过Session来进行传值            list=(List)session.getAttribute("TRANS");            if(list.size()>0){                int id=0;//表示序号                Trans ts;//记得要引入类包                for(int i=0;i<list.size();i++){//依次遍历容器中的元素                    ts=new Trans();                    ts=(Trans)list.get(i);                    %>                     <tr>                        <th><%=id+=1 %></th><!--获取容器元素的属性值-->                        <th><%=ts.getBk() %></th>                    <th><%=ts.getUa() %></th>                        <th><%=ts.getUb() %></th>                        <th><%=ts.getUc() %></th>                    </tr>                    <%                 }            }        }    %>    </table>  </body></html>

到这里我所有的代码就结束了。接下来看看执行的效果:

点击生成报表,页面切换如下:



到这里,可以说一个简单的报表生成了。这里我并没有使用CSS来渲染界面,感觉这太费时间了。而且这应该是Web前端要做的事。对了,上图有一个疑问就是大家发现我的Tomcat的默认端口是8000,初始的默认不是8080吗?这里是由于我的8080端口被别的软件给使用了,所以我只能将默认端口改成了8000。这对我们生成的报表不影响。

怎么样,简单吧。一个Web版的报表的实现总共就五步。其实只要你把JSP和Servlet弄懂了,相信你对Spring和Struct这些框架不在话下。这些框架都是从Servlet演化过来的。无非就是向用户屏蔽了一些底层的代码实现,是用户可以不要考虑底层的代码。直接拿来用就行了。