`
yaojialing
  • 浏览: 253093 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

数据导入与实时进度条实现

    博客分类:
  • JAVA
阅读更多

                                   digiflow数据导入与实时进度条实现

 

本文档只是稍微解析下数据导入的流程,以及讲解实时进度条实现方法

 

数据批量导入流程

1、客户把.txt数据打包成.gz文件,发给我们。

GZ文件格式,每个文件的第一行是唯一的数据,导入完成后要插入到ImportRecord

名字格式:DigiFlow_南宁 - 平安出单中心_20100201_000100ECHW8P8708.txt

内容格式:以”||”为分割符

比如:00||000100ECHW8P8708||8||18:08:17

00代表表名称

000100ECHW8P8708 代表这个文件的唯一标识

 

2JAVA解压缩GZ文件

JAVA提供了GZIPInputStream 解压API,把里面的内容写入到txt文件里。

 

3、解压的文件临时存放目录

一种是在安装的TOMCAT根目录下新建file目录,然后System.getProperty("user.dir") + "/file/"

二种是System.getProperty("java.io.tmpdir")得到的是tomcat临时目录

项目中用到的是第一种

 

4读取解压的文件

if("00".equals(fileinfos[0]))  读取到第一行时,根据UID判断是否导入过该文件。如果导入过则系统提示,并删除解压的文件。如果没有导入过,则继续执行下一步直到导入完成,完成后再插入这个文件的唯一标识。如:000100ECHW8P8708

 

读取到其他行时,获取其UID,判断是否插入过该记录。如果插入过,则执行update。如果没插入过,则执行insert.

 

5、拼SQL实现方式实现DMLinsertupdate

程序中的insertupdate语句是获得文件的中的列名之后,通过表名和列明去查找相应的字段信息,有的字段是varcharchardatetime型则加上‘’号。详细参见源码bossdataimportBusinessDAOImpl.java类的getStringType()方法。

 

 

 

 

AJAX实现实时WEB进度条

我们为了改善用户界面,通常会在处理量大或者是网络速度较慢的时候,给用户显示一个处理进度,让用户心理有底,增强用户等待结果的耐心,以改善用户体验。为了达到这个效果,通常做法有两大类:简单等待和真实的处理进度,本文着重讨论第二种方法的实现。

 

1)简单的等待界面:这种做法之所以说简单,就是在用法发送了处理命令后,立即在页面的某个地方替换一个waiting的图片,比如一个转圈的GIF,一张Loading的图片等,这种不称之为进度条,顶多就是个等待条,但通常还是可以给用户带来那么点满足,在业务量不大的情况下,也够用了,例子参见http://www.belitastone.com的首页。

 

2)真实的等待进度:比如说,我要在B/S系统中实现一个数据导入的功能,数据文件总共有100个,每个文件包含成千上万的数据,导入过程可能需要15分钟,那么我还用一个图片在那边打转吗?现在这样还是不够的,我可能需要让使用者知道,我当前处理的是第几个文件,还剩下几个,处理的百分比,并显示一个加载的真实进度条,这个进度条要如实反映处理的百分比。

 

实现1:由于用户处理的数据量大,可以在文件导入过程中,循环计算进度,并将进度信息存储在上下文中,并在前台页面定时从上下文读取进度数据,并在页面显示。这种方法思路比较直接。

 

实现2:使用观察者模式,实现进度主动通知。思路是:在文件导入过程中,计算进度信息,并将进度数据通知给观察者,前台页面定时向观察者咨询进度,并将进度显示到页面中。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhengtanyun/archive/2009/07/06/4325528.aspx

 

 

我来说下我的实现方式

关于他说的“实现1”,说把进度信息存储到上下文,这个貌似有问题,这个上下文是servlet上下文?据我所知,上下文作用域和Application作用域一样大,进度条每个用户执行不同的导入操作,存到上下文做什么,还不乱套?

 

我的实现方式和“实现2”有点像。思路是:在文件导入过程中,循环计算进度信息,并将进度数据放入SESSION,前台页面通过AJAX定时调用,获取进度,并将进度显示到页面中.

进度数据有:总的数据量、已导入数据量、已经上传时间。

 

另外一种情况:当正在进行导入时,点击了别的页面,从而页面上的进度条就没有了,而后台却还在运行。有几种方法,一是弹出模式对话框,在模式框里面进行导入,但是这样还有点麻烦。二是当用户点击了别的页面再回到导入页面时,又重新读取SESSION中的进度信息。这需要在ACTION中设置一个全局变量来作为是否正在执行导入操作的标记。

 

 

 

最终效果图:(见附件) 

 效果图

 

 

代码实现参考源代码manage中的DigimpAction.java以及dimpImport.jsp

核心代码如下:

ACTION 部分代码

//	读取数据导入实时状态
	public ActionForward doStatus(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		// 设置该响应不在缓存中读取
		response.addHeader("Expires", "0");
		response.addHeader("Cache-Control",
				"no-store, no-cache, must-revalidate");
		response.addHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setCharacterEncoding("utf-8");          
	    response.setContentType("text/html; charset=utf-8");          
		int totalSize = 0;// 总数据的条数
		int bytesRead = 0;// 已导入数据条数
		long getElapsedTimeInSeconds=0;// 获得已经上传得时间
		HttpSession session = request.getSession(false);
        if (session.getAttribute("TOTALSIZE")  != null) {
        	if(count == 0){
        		session.removeAttribute("TOTALSIZE");
        	}else{
        		totalSize=Integer.parseInt(session.getAttribute("TOTALSIZE").toString());
            	
        	}
        }
        if (session.getAttribute("BYTESREAD")  != null) {
        	if(count == 0){
        		session.removeAttribute("BYTESREAD");
        	}else{
        		bytesRead=Integer.parseInt(session.getAttribute("BYTESREAD").toString());
        	}
        }
        if (session.getAttribute("STARTTIME")  != null) {
        	long stime=Long.parseLong((String)session.getAttribute("STARTTIME"));
        	getElapsedTimeInSeconds=(System.currentTimeMillis() - stime) / 1000;
        }
		
		//计算上传完成的百分比
        String percentComplete="0";
        if(totalSize > 0){
        	double k = (double)bytesRead/totalSize*100; 
        	BigDecimal big=new BigDecimal(k);  
        	percentComplete = big.setScale(2,BigDecimal.ROUND_HALF_UP).toString(); 
        }
		//获得上传已用的时间
		long timeInSeconds = getElapsedTimeInSeconds;
		//计算平均上传速率
		//double uploadRate = bytesRead / (timeInSeconds + 0.00001);
		//System.out.println("**************计算平均上传速率="+bytesRead);
		// 计算总共所需时间
		//double estimatedRuntime = totalSize / (uploadRate + 0.00001);
		
		//将上传状态返回给客户端
		response.getWriter().println("<b>Import Status:</b><br/>");
		if (bytesRead != totalSize) {
			response.getWriter().println(
					"<div class=\"prog-border\"><div class=\"prog-bar\" style=\"width: "
							+ percentComplete + "%;\"></div></div>");
			response.getWriter().println(
					"Imported: " + bytesRead + " out of " + totalSize
							+ " Records (" + percentComplete + "%) <br/>");
			response.getWriter().println(
					"Runtime: " + formatTime(timeInSeconds) + " <br/>");
		} else {
			response.getWriter().println(
					"Imported: " + bytesRead + " out of " + totalSize
							+ " Records<br/>");
			response.getWriter().println("Complete.<br/>");
		}
        //如果文件已经导入完毕
		if (bytesRead == totalSize) {
			response.getWriter().println("<b>Imported complete.</b>");
		}
		return null;
	}
	private String formatTime(double timeInSeconds) {
		long seconds = (long) Math.floor(timeInSeconds);
		long minutes = (long) Math.floor(timeInSeconds / 60.0);
		long hours = (long) Math.floor(minutes / 60.0);

		if (hours != 0) {
			return hours + "hours " + (minutes % 60) + "minutes "
					+ (seconds % 60) + "seconds";
		} else if (minutes % 60 != 0) {
			return (minutes % 60) + "minutes " + (seconds % 60) + "seconds";
		} else {
			return (seconds % 60) + " seconds";
		}
	}
	//页面调用此方法,检查导入工作是否正在进行时,0:无 1:正在进行
	public int checkImportStatus(){
		return count;
	}

 

 

 

 

dimpImport.jsp  部分代码

<script type="text/javascript">
	var xmlHttp; 
	function createXMLHttpRequest()//创建XMLHttpRequest对象 
	{ 
		if(window.ActiveXObject){ 
			xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 
		}else if(window.XMLHttpRequest){ 
			xmlHttp = new XMLHttpRequest(); 
		} 
	} 
    //导入程序入口
	function tijiao(){
	    document.forms[0].action=" ";
		document.forms[0].submit();
		go();
	}
	function go() 
	{
		createXMLHttpRequest();//创建XMLHttpRequest对象
		xmlHttp.onreadystatechange = callBack;//设置回调函数 
		var url = "digimp.do?method=doStatus";//请求的地址 
		var button = document.getElementById("go"); 
		button.disabled = true;//设置按钮不可用 
		xmlHttp.open("post",url,true);//打开对服务器的连接 
		xmlHttp.send();//发送请求 
	} 
	function callBack() 
	{ 
		if(xmlHttp.readyState == 4){ 
			if(xmlHttp.status == 200){
				setTimeout("go()",500);//定时调用
				document.getElementById('status').innerHTML =xmlHttp.responseText;
			} 
		} 
	}
	//检查是否有正在进行的导入操作
	function page_init(){
		DigimpAction.checkImportStatus(function callback_init(data){
			if(data != '0'){
				document.getElementById("go").disabled = true;
				go();
			}else{
				document.getElementById("go").disabled = false;
			}
		});
	}
	
</script>
<body onload="page_init();">
    	<!-- 这里显示进度条 -->
<div id="status"></div>
</body>

 

 

 

  • 大小: 71.1 KB
11
0
分享到:
评论
2 楼 strive708 2012-09-02  
不错,正在试着加入自己的项目中,感谢。
1 楼 hbszyandong 2010-09-28  
,不错,借来用一下。

相关推荐

    JAVA实现模拟导入数据/上传文件进度条

    使用Servlet、jsp、jQuery、ajax实现模拟数据导入,文件上传进度条功能。

    ASP.NET实现EXCEL数据导入进度条ajax

    ASP.NET实现EXCEL数据导入进度条ajax。有已经实现的工程源代码。有进度条和百分比统计,已导入数量和总数统计。

    C# EXCEL数据导入进度条aspnet.rar

    因项目需要,需要导入大量excel,为体现页面友好度,不让客户认为页面死机了,故添加了页面实时显示...ASP.NET实现EXCEL数据导入进度条ajax。有已经实现的工程源代码。有进度条和百分比统计,已导入数量和总数统计。

    POI实现Excel导入导出并附带加载进度条

    这是一个Excel表格导入与导出功能,Excel美化,并且添加了进度条,丢上Eclipse直接运行使用,附带测试数据与说明。Java项目使用maven搭建。

    ASP.net AJAX进度条实例(批量插入大量数据)

    该示例使用简单,完成插入指定数量的数据,ajax写入数据库,并显示精准进度,实时返回运行过程。对于大量插入数据库的操作,可以做到无刷,不超时; 目录结构: Css/style.css -------------进度条样式 Js/...

    C# Oracle批量插入数据进度条的实现代码

    由于项目需求,需要将Excel中的数据进过一定转换导入仅Oracle数据库中。考虑到当Excel数据量较大时,循环Insert语句效率太低,故采用批量插入的方法。在插入操作运行时,会造成系统短暂的“卡死”现象。为了让用户...

    java数据导入实时提示

    能够实现数据导入时进度条提示,显示导入时间,导入百分比等数据

    C# 进度条显示处理进度

    实现线程处理信息时,传出处理进度值,显示到进度条中。(以前不会,在网上找了程序改着用,但是代码过于冗余复杂。现在理解相关内容后自己写了一个浅显易懂的实现方法)

    java上传(带进度条)

    以*.flv格式为例,实现IO流文件上传,并完成进度条。

    C#编程---进度条显示处理进度.rar

    导入管理器ImportMgr类调用信息处理类ProcessInfo进行导入数据操作,调用进度条状态窗口类frmstatus显示导入进度。当导入数据完成时广播导入数据完成事件ImportDone。信息处理类ProcessInfo使用线程函数...

    ASP.NET 上传文件显示进度条

    原来的实现比较粗糙。 经过修改主要显示 进度条,文件名称,文件大小,文件上传速度等功能。 经过修改的显示界面大概如下 完成百分比:68% 文件名称:asp_net_progressbar.rar 文件大小:259KB 上传速度:150KB/...

    C#实现EXCEL表格内容快速导入EXCEL报表

    4.引用Microsoft.Office.Interop.Excel和Spire.Xls分别实现文件的导入和导入报表文件、导入表格数据,System.Threading功能实现进度条 5.实现批量处理,快速处理大量数据 运行结果演示截图在文件夹里

    SuperMap Objects Java 进度条

    该示例程序通过iobjects JAVA实现导入数据的进度条的功能。

    Ajax批量上传显示进度条

    用Ajax实现文件上传功能,上传过程可以显示进度条。。

    DotNet带进度条下载更新升级组件(V1.1)

    DotNet 2.0提供了ClickOnce可以很好的实现功能。但是绝大部分程序员还是愿意在自己开发的程序内部提供升级功能。升级的原理实现虽然不难,但是对于很多新手来说还是有一定的困难。为此我将下载升级的功能进行了封装...

    JS+WCF实现进度条实时监测数据加载量的方法详解

    本文实例讲述了JS+WCF实现进度条实时监测数据加载量的方法。分享给大家供大家参考,具体如下: 背景 由于项目中需要导入大量数据到memcache中 需要用WCF调取11万条数据,由于那边多级联查和排序,所以比较慢(1分钟...

    jsp网站 实现Excel导入与导出功能.zip

    实现Excel导入与导出功能,并WEB页面附带进度条对Excel进行美化如:设置背景色、线条、格子大小等。 使用步骤很简单 1.解压下载好的项目,这里需要进行基本配置如Maven配置,本项目中使用的是jdk 1.8。 2.启动...

    C#中读取excel文件中数据并导入dataGridView添加读取ProgressBar进度及当前读取条目挨个

    完整挨个读取excel文件数据,并添加进度条progressbar和当前读取条目数据

    java实现csv导出千万级数据实例

    轻松解决普通poi形式导出Excel的中出现的栈溢出问题,此资源可实现千万级数据分批导出csv文件,测试实现16500000条数据大概80秒左右;具体表里内容。

Global site tag (gtag.js) - Google Analytics