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

今天下午没事干。主要是论文没有什么进展,唉!读研苦逼啊。突然想玩玩其他的,记得上次用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层的代码:

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;
	}

}

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

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;
	}
}

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

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。

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 {
<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
	}

}

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

<!--首先要记得将需要的类包导进来-->
<%@ 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演化过来的。无非就是向用户屏蔽了一些底层的代码实现,是用户可以不要考虑底层的代码。直接拿来用就行了。

时间: 2024-08-27 19:02:43

手把手教你用Java制作原生态的报表的相关文章

手把手教你实现Java权限管理系统 后端篇(十二):解决跨域问题

什么是跨域? 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 如果一个请求地址里面的协议.域名和端口号都相同,就属于同源. 举个栗子 判断下面URL是否和 http://www.a.com/a/a.html 同源 http://www.a.com/b/b.html 同源 http://www.b.com/a/a.html 不同源,域名不相同 https://www.a.com/b/b.html 不同源,协议不相同 htt

手把手教你使用Java实现一个神经网络

首先看一下运行效果: 下面是项目整体目录: 0.实现神经网络总览 神经网络由层.神经元.权重.激活函数和偏置组成.每层都有一个或者多个神经元,每一个神经元都和神经输入/输出连接,这些连接就是权重. 需要重点强调一下,一个神经网络可能有很多隐含层,也可能一个没有,因为每层的神经元数目也可能不同.然而,输入输出层的神经元个数分别等于神经输入/输出的个数. 我们为了实现,需要定义以下的类: Neuron: 定义人工神经元 NeuralLayer: 抽象类,定义一个神经元层. InputLayer: 定

手把手教你用java实现syslog消息的收发,学不会你打我喽!

大家好,我是道哥,专注于后端java开发,喜欢写作和分享.如果觉得文章对你有用,那就点个赞呗!如果能转发那是对道哥最大的支持! syslog的定义 见文知义,syslog,从英文名字上可以看出是指系统日志. 以下内容摘自百度百科: Syslog常被称为系统日志或系统记录,是一种用来在互联网协议(TCP/IP)的网上中传递记录档消息的标准.这个词汇常用来指涉实际的syslog 协议,或者那些提交syslog消息的应用程序或数据库. syslog协议属于一种主从式协议:syslog发送端会发送出一个

手把手教你实现Java权限管理系统 前端篇(十四):菜单功能实现

菜单功能实现 菜单接口封装 菜单管理是一个对菜单树结构的增删改查操作. 提供一个菜单查询接口,查询整颗菜单树形结构. http/modules/menu.js 添加 findMenuTree 接口. import axios from '../axios' /* * 菜单管理模块 */ // 保存 export const save = (data) => { return axios({ url: '/menu/save', method: 'post', data }) } // 删除 ex

手把手教你实现Java权限管理系统 前端篇(十六):系统备份还原

系统备份还原 在很多时候,我们需要系统数据进行备份还原.我们这里就使用MySql的备份还原命令实现系统备份还原的功能. 后台接口准备 系统备份还原是对数据库的备份还原,所以必须有后台接口的支持,我们准备好了接口,相关内容可以查阅后台篇. backup:系统备份创建接口,会在服务端_backup目录下生成以时间戳相关的备份目录,目录下有MySQL的备份SQL. delete:系统备份删除接口,传入页面查询得到的备份名称作为参数,删除服务端备份记录. findRecord:系统备份查询接口,查询所有

手把手教你实现Java权限管理系统 前端篇(十五):嵌套外部网页

嵌套外部网页 在有些时候,我们需要在我们的内容栏主区域显示外部网页.如查看服务端提供的SQL监控页面,接口文档页面等. 这个时候就要求我们的导航菜单能够解析嵌套网页的URL,并根据URL路由到相应的嵌套组件.接下来我们就讲解具体实现方案. 实现原理 1. 给菜单URL添加嵌套网页前缀,如果是服务端网页,除内部URL外,以iframe:前缀开头,外部网页直接以http[s]完整路径开头. 2. 路由导航守卫在动态加载路由时,检测到如果是外部嵌套网页,则绑定IFrame嵌套组件,最后用IFrame来

【转】手把手教你源代码制作龙芯64位系统

Reference:http://zdbr.net.cn/download/Loongson64-2.0.htm 手把手教你源代码制作龙芯64位系统 (交叉编译版本)2.0 正式版 作者:孙海勇 更新日志: 2009年9月20日 :改进制作步骤两处 2009年9月20日 :修改笔误五处 2009年5月29日 :修改笔误七处 2009年5月9日 :修改工具链的制作 2009年5月3日 :v2.0 正式版发布 2008年10月19日 :v2.0-pre2 发布 2008年9月14日 农历八月十五(中

Android开发之手把手教你写ButterKnife框架(二)

欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52664112 本文出自:[余志强的博客] 上一篇博客Android开发之手把手教你写ButterKnife框架(一)我们讲了ButterKnife是什么.ButterKnife的作用和功能介绍以及ButterKnife的实现原理. 本篇博客主要讲在android studio中如何使用apt. 一.新建个项目, 然后创建一个module名叫processor 新建m

Android消息推送:手把手教你集成小米推送

前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 该文档基于小米推送官方Demo,并给出简易推送Demo 看该文档前,请先阅读我写的另外两篇文章: 史上最全解析Android消息推送解决方案 Android推送:第三方消息推送平台详细解析 目录 1. 官方Demo解析 首先,我们先对小米官方的推送Demo进行解析. 请先到官网下载官方Demo和SDK说明文档 1.1 Demo