`
923723914
  • 浏览: 632823 次
文章分类
社区版块
存档分类
最新评论

Ext4+Servlet+HTML5实现实时获取文件上传进度、本地预览、文件拖拽上传的相册实例

 
阅读更多


今天晚上花了几个小时的功夫做了一个相册,类似于QQ空间的文件上传,不过我用的Ext+HTML5等新的技术,结合Servlet上传文件。有几个特点:

  • 文件拖拽上传
  • 实时获取上传进度
  • 本地预览
  • 与Ext结合起来
说了这么多,还是贴几张图给大家吧!!

这个是没有做任何操作时候的窗口

拖动图片的时候,提示将图片拖动到指定的区域

这个是拖拽进去后,生成了本地预览,并有相应的详细信息

这个是上传成功后显示的信息。这里可能是本地的原因,一下子就上传完了,没有体现出百分比来。大概就是这个样子了!下面说下实现:
首先构建Ext窗口:
//创建相册窗口
	var win = Ext.create('Ext.window.Window', {
				title : 'Ext相册',
				width : 700,
				height : 400,
				iconCls : 'ablum',
				layout : 'fit',
				plain : false,
				items : [view],
				buttons : [{
							text : '上传', //上传按钮
							handler : upload,
							iconCls : 'upload'
						}, {
							text : '清空',
							handler : function() {
								store.removeAll();
							},
							iconCls : 'clear'
						}]
			});
	win.show();

创建像是图片的容器:
//创建图片数据模型 ,数据源需要
	var PhotoModel = Ext.define('ImageModel', {
				extend : 'Ext.data.Model',
				fields : [{name : 'name'},
						{name : 'type'}, 
						{name : 'size', type : 'float'},
						{name : 'lastmod', type : 'date',dateFormat : 'timestamp'},
						{name : 'file'},
						{name : 'src'}]
			});

	//创建数据源
	var store = Ext.create("Ext.data.Store", {
				model : PhotoModel
			});

	var ddtip;
	
	//图片提示模板
	var tiptpl = '名称:{0}<br/>' +
			  '类型:{1}<br/>' +
			 '大小:{2}<br/>' + 
			 '修改时间:{3}<br/>'
	
	//创建图片存放的容器
	var view = Ext.create('Ext.view.View', {
				store : store, //指定数据源
				tpl : [ //设置展示模板
						'<tpl for=".">',
						'<div class="thumb-wrap" id="{name}">',
						'<div class="upload-progress">0%</div>',
						'<div class="thumb"><img src="{src}"></div>',
						'<span>{name}</span></div>', '</tpl>',
						'<div class="x-clear"></div>'],
				style : {
					backgroundColor : '#FFFFFF',
					fontFamily : '微软雅黑'
				},
				multiSelect : true,
				trackOver : true,
				overItemCls : 'x-item-over',
				itemSelector : 'div.thumb-wrap',
				emptyText : '没有显示的相片',
				autoScroll : true,
				listeners : {
					'afterrender' : function() {
						//创建用户拖拽提示
						ddtip = view.el.createChild({
									tag : 'div',
									cls : 'dd-tip',
									html : '请将图片拖动到这里'
								});
						//创建相片浮动提示
						Ext.create('Ext.tip.ToolTip', {
								target : view.el,
								delegate : view.itemSelector,
								trackMouse : true,
								renderTo : Ext.getBody(),
								anchor : 'right',
								listeners : {
									beforeshow : function(tip) {
										var record = view
													.getRecord(tip.triggerElement);
											tip.update(Ext.String.format(
													tiptpl, record
															.get('name'),
													record.get('type'), record
															.get('size'),
													Ext.Date.format(
															record.get('lastmod'),
															'Y年m月d日 H时i分')));
										 
									}
								}
							});
					}
				}
			});

添加监听页面拖拽事件:
//给body添加事件,如果有拖拽的话提示用户拖拽到指定区域
	Ext.getBody().on('dragover', function(e) {
				ddtip.show();
			});
	//当用户拖拽离开时隐藏提示信息
	Ext.getBody().on('dragleave', function(e) {
				ddtip.hide();
			});
	//当用户拖拽到指定区域时,隐藏提示信息
	view.el.on('dragenter', function(e) {
				e.stopPropagation();
				e.preventDefault();
				ddtip.hide();
				view.el.highlight();
			});

	//当用户拖拽离开指定区域时显示提示信息
	view.el.on('dragleave', function(e) {
				e.stopPropagation();
				e.preventDefault();
				ddtip.show();
			});

	//很关键!!当用户拖拽文件并放下的时候触发时间
	view.el.dom.ondrop = function(e) {
		e.stopPropagation();
		e.preventDefault();
		ddtip.hide();//隐藏提示信息
		//处理用户拖拽过来的文件
		process(e.dataTransfer.files);
	};

处理用户拖拽过来的文件:
function process(files) {
		var count = 0;
		for (var i = 0; i < files.length; i++) {
			var file = files[i];//这个一个File对象
			//创建一个相片数据实例,保存名称,大小,类型,修改日期,文件等信息
			var photo = Ext.ModelManager.create({
						name : file.fileName,
						size : file.fileSize,
						type : file.type,
						file : file,
						lastmod : file.lastModifiedDate
					}, PhotoModel);
			//添加到数据源中,这时候容易会发生相应的变化
			store.add(photo);
			//通过FileReader对象获取预览
			var reader = new FileReader();
			//当读取完成之后执行的回调
			reader.onload = (function(p) {
				return function() {
					count++;
					//将获取到的Base64格式的图片数据,存放起来
					p.data.src = this.result;
					if (count == files.length) {
						//当所有图片都加载完了之后,渲染图片
						view.refresh();
					}
				}
			})(photo);//这个地方利用了JS的闭包原理
			//读取图片
			reader.readAsDataURL(file);
		}
	}
	

处理上传方法:
function upload(){ //执行上传
		store.each(function(photo){//遍历数据源的数据
			var progress = Ext.get(view.getNode(photo)).down('div.upload-progress');//显示进度信息
			progress.show();
			var xhr = new XMLHttpRequest(); //初始化XMLHttpRequest
			xhr.open('post', 'upload', true);
			xhr.upload.onprogress = function(p) { //添加数据上传进度,获取实时的上传进度
				return function(e) {
					if (e.lengthComputable) {
						var percentage = Math.round((e.loaded * 100) / e.total);
						progress.update(percentage + "%");
					}
				}
			}(progress);
			xhr.upload.onload = function(p) { //当上传完之后执行的回调函数
				return function(e) {
					progress.update("上传成功!");
				}
			}(progress);
			var fd = new FormData(); //这里很关键,初始化一个FormData,并将File文件发送到后台
			fd.append("file", photo.data.file);
			xhr.send(fd);
		});
	}

Servlet实现文件上传的代码:
@SuppressWarnings("unchecked")
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String path = request.getSession().getServletContext().getRealPath("\\upload");
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);

		try {
			List<FileItem> list = (List<FileItem>) upload.parseRequest(request);
			for (FileItem fileItem : list) {
				String fileName = fileItem.getName();
				File file = new File(path + "\\" + fileName);
				fileItem.write(file);
				fileItem.delete();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

就这样,这个相册实例就完成了

------------------------------------------------------------------------------分割线---------------------------------------------------------------------------------

2012-05-14更新:
  • 增加了通过资源管理器选择文件功能
  • 修复上传进度显示BUG
  • 增加相片右键菜单
  • 上传更改为上传全部项和上传选中项
  • 增加图片浏览器功能
  • 图片浏览器支持拖动、双击最大化/还原、更改尺寸
  • 图片浏览器支持对数据源里面的图片进行导航
  • 图片浏览器图片的放大和缩小
由于更新的比较仓促,写的代码质量不是很高,应该将图片浏览器封装成一个对象,并且图片旋转的功能没有完成。这些工作就留给大家伙自己实现吧,图片旋转的代码网上都有。贴图给大家:

通过点击添加按钮选取文件

相片右键菜单

图片查看器,双击相片可以启动。支持图片放大,导航!
确定只能在chrome下运行,在firefox下运行有错,不是不能调,只是懒得调了!
源码等会会放到下载区里面,只是CSDN有延迟,找不到链接!

---------------------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------

大家测试最好用最新版的Google Chrome浏览器。

Ext还能做什么?只有想不到的,没有做不到了,进入http://blog.csdn.net/leecho571/article/details/8207102感受Ext带来的新的体验
在chrome下运行有效,firefox还在测试,IE忽略不计!!讨厌IE!!
最后打下小广告,
看文章评论一下是美德,你的评论是我最大的动力!!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics