现在的位置: 首页 > 综合 > 正文

Extjs上传附件实战开发,实现批量上传及在线预览功能(二)

2012年09月08日 ⁄ 综合 ⁄ 共 9285字 ⁄ 字号 评论关闭

SWFUpload的使用:

        SWFUpload采用czpae86的UploadPanel二次开发,在此鸣谢。

        SWFUpload下载最新版本swfupload.swf.v2.5.0.beta3.2.zip,你会发现文件夹里只有swfupload.swf文件,并没有swfupload.js----调用flash的接口文件,定义了很多函数和参数,这里郁闷了半天,后面下载了SWFUpload_v250_beta_3_samples.zip,果断在实例文件夹里找到了这个最新版本的swfupload.js文件,两个文件与czpae86的UploadPanel文件放在同一目录,使用该面板的方法请参照他发的博客,其实也很简单,如下:

Ext.onReady(function(){
	Ext.QuickTips.init();
	new Ext.Window({
		width : 650,
		title : 'swfUpload demo',
		height : 300,
		layout : 'fit',
		items : [
			{
		                  xtype:'uploadPanel',
				border : false,
				fileSize : 1024*550,//限制文件大小
				uploadUrl : 'uploadFiles.action',
				flashUrl : 'swfupload.swf',
				filePostName : 'file', //后台接收参数
				fileTypes : '*.*',//可上传文件类型
				postParams : {savePath:'upload\\'} //上传文件存放目录
			}
		]
	}).show();
});

uploadPanel.js修改如下:

var keel={};

keel.UploadPanel = function(cfg){
	this.width = 510;
	this.height = 200;
	Ext.apply(this,cfg);	
	this.gp = new Ext.grid.EditorGridPanel({//修改为可编辑表格
		border :false,
		selModel: new Ext.grid.RowSelectionModel({

        }),
		store: new Ext.data.Store({
			fields:['id','name','type','size','state','percent','detail']
		}),
	    columns: [
	    	new Ext.grid.RowNumberer(),
	        {header: '文件名', width: 150, sortable: true,dataIndex: 'name', menuDisabled:true},
	        {header: '类型', width: 50, sortable: true,dataIndex: 'type', menuDisabled:true},
	        {header: '大小', width: 70, sortable: true,dataIndex: 'size', menuDisabled:true,renderer:this.formatFileSize},
	        {header: '文件说明', width: 100, sortable: true,dataIndex: 'detail', menuDisabled:true,editor: {xtype: 'textfield'}},//-------二次修改------
	        {header: '进度', width: 150, sortable: true,dataIndex: 'percent', menuDisabled:true,renderer:this.formatProgressBar,scope:this},
	        {header: '状态', width: 70, sortable: true,dataIndex: 'state', menuDisabled:true,renderer:this.formatFileState,scope:this},
	        {header: ' ',width:40,dataIndex:'id', menuDisabled:true,renderer:this.formatDelBtn}       
	    ]			
	});
	this.setting = {
		upload_url : this.uploadUrl, 
		flash_url : this.flashUrl,
		file_size_limit : this.fileSize || (1024*50) ,//上传文件体积上限,单位MB
		file_post_name : this.filePostName,
		file_types : this.fileTypes||"*.*",  //允许上传的文件类型 
        file_types_description : "All Files",  //文件类型描述
        file_upload_limit : "0",  //限定用户一次性最多上传多少个文件,在上传过程中,该数字会累加,如果设置为“0”,则表示没有限制 
        //file_queue_limit : "10",//上传队列数量限制,该项通常不需设置,会根据file_upload_limit自动赋值              
		post_params : this.postParams||{Detail:'ok'} ,
		use_query_string : true,
		debug : false,
		button_cursor : SWFUpload.CURSOR.HAND,
		button_window_mode : SWFUpload.WINDOW_MODE.TRANSPARENT,
		custom_settings : {//自定义参数
			scope_handler : this
		},
		file_queued_handler : this.onFileQueued,
		swfupload_loaded_handler : function(){},// 当Flash控件成功加载后触发的事件处理函数
		file_dialog_start_handler : function(){},// 当文件选取对话框弹出前出发的事件处理函数
		file_dialog_complete_handler : this.onDiaogComplete,//当文件选取对话框关闭后触发的事件处理
		upload_start_handler : this.onUploadStart,// 开始上传文件前触发的事件处理函数
		upload_success_handler : this.onUploadSuccess,// 文件上传成功后触发的事件处理函数 
		swfupload_loaded_handler : function(){},// 当Flash控件成功加载后触发的事件处理函数  
		upload_progress_handler : this.uploadProgress,
		upload_complete_handler : this.onUploadComplete,
		upload_error_handler : this.onUploadError,
		file_queue_error_handler : this.onFileError
	};
	keel.UploadPanel.superclass.constructor.call(this,{				
		tbar : [
			{text:'添加文件',iconCls:'btn-add',ref:'../addBtn'},'-',
			{text:'上传',ref:'../uploadBtn',iconCls:'btn-up',handler:this.startUpload,scope:this},'-',
			{text:'停止上传',ref:'../stopBtn',iconCls:'btn-cancel',handler:this.stopUpload,scope:this,disabled:true},'-',
			{text:'删除所有',ref:'../deleteBtn',iconCls:'btn-clear',handler:this.deleteAll,scope:this},'-'
		],
		layout : 'fit',
		items : [this.gp],
		listeners : {
			'afterrender':function(){
				var em = this.getTopToolbar().get(0).el.child('em');
				var placeHolderId = Ext.id();
				em.setStyle({
					position : 'relative',
					display : 'block'
				});
				em.createChild({
					tag : 'div',
					id : placeHolderId
				});
				this.swfupload = new SWFUpload(Ext.apply(this.setting,{
					button_width : em.getWidth(),
					button_height : em.getHeight(),
					button_placeholder_id :placeHolderId
				}));
				this.swfupload.uploadStopped = false;
				Ext.get(this.swfupload.movieName).setStyle({
					position : 'absolute',
					top : 0,
					left : 0
				});				
			},
			scope : this,
			delay : 100
		}
	});
}
Ext.extend(keel.UploadPanel,Ext.Panel,{
	toggleBtn :function(bl){
		this.addBtn.setDisabled(bl);
		this.uploadBtn.setDisabled(bl);
		this.deleteBtn.setDisabled(bl);
		this.stopBtn.setDisabled(!bl);
		this.gp.getColumnModel().setHidden(7,bl);
	},
 	onUploadStart : function(file) {  
	   var post_params = this.settings.post_params;  
	   Ext.apply(post_params,{//处理中文参数问题
	   		//fileName : file.name,
	        fileName : encodeURIComponent(file.name)
	   });  
	   this.setPostParams(post_params); //-------二次修改------
	   var det="";
	   var me = this.customSettings.scope_handler;
	   var ds = me.gp.store;
	   for(var i=0;i<ds.getCount();i++){
			var record =ds.getAt(i);
			if(record.get('id')==file.id)
		       	det=record.get('detail');
	   }
	   this.addFileParam(file.id ,"detail",det);//-------二次修改------
	},
	startUpload : function() {
		if (this.swfupload) {
			if (this.swfupload.getStats().files_queued > 0) {
				this.swfupload.uploadStopped = false;
				this.toggleBtn(true);
				this.swfupload.startUpload();
			}
		}
	},
	formatFileSize : function(_v, celmeta, record) {
		return Ext.util.Format.fileSize(_v);
	},
	formatFileState : function(n){//文件状态
		switch(n){//-------二次修改------
			case -1 : return '<img src="/skin/images/152.png"/><span style="color:green;">  未上传</span>';
			break;
			case -2 : return '<img src="/skin/images/147.png"/><span style="color:brown;">  正在上传</span>';
			break;
			case -3 : return '<img src="/skin/images/151.png"/><span style="color:red;">  上传失败</span>';
			break;
			case -4 : return '<img src="/skin/images/102.png"/><span style="color:green;">  上传成功</span>';
			break;
			case -5 : return '<img src="/skin/images/050.png"/><span style="color:#CECEFF;">  取消上传</span>';
			break;
			default: return n;//-------二次修改------
		}
	},
	formatProgressBar : function(v){
		var progressBarTmp = this.getTplStr(v);
		return progressBarTmp;
	},
	getTplStr : function(v){
		var bgColor = "orange";
	    var borderColor = "#008000";
		return String.format(
			'<div>'+
				'<div style="border:1px solid {0};height:10px;width:{1}px;margin:4px 0px 1px 0px;float:left;">'+		
					'<div style="float:left;background:{2};width:{3}%;height:10px;"><div></div></div>'+
				'</div>'+
			'<div style="text-align:center;float:right;width:40px;margin:3px 0px 1px 0px;height:10px;font-size:12px;">{3}%</div>'+			
		'</div>', borderColor,(90),bgColor, v);
	},
	onUploadComplete : function(file) {
		var me = this.customSettings.scope_handler;
		if(file.filestatus==-4){
			var ds = me.gp.store;
			for(var i=0;i<ds.getCount();i++){
				var record =ds.getAt(i);
				if(record.get('id')==file.id){
					record.set('percent', 100);
					if(record.get('state')!=-3){
						record.set('state', file.filestatus);
					}
					record.commit();
				}
			}
		}
		
		if (this.getStats().files_queued > 0 && this.uploadStopped == false) {
			this.startUpload();
		}else{			
			me.toggleBtn(false);
			me.linkBtnEvent();
		}		
	},
	onFileQueued : function(file) {
		var me = this.customSettings.scope_handler;
		var rec = new Ext.data.Record({
			id : file.id,
			name : file.name,
			size : file.size,
			type : file.type,
			state : file.filestatus,
			percent : 0
		})
		me.gp.getStore().add(rec);
	},
	onUploadSuccess : function(file, serverData) {
		var me = this.customSettings.scope_handler;
		var ds = me.gp.store;
		if (Ext.util.JSON.decode(serverData).success) {			
			for(var i=0;i<ds.getCount();i++){
				var rec =ds.getAt(i);
				if(rec.get('id')==file.id){
					rec.set('state', file.filestatus);
					rec.commit();
				}
			}			
		}else{
			for(var i=0;i<ds.getCount();i++){
				var rec =ds.getAt(i);
				if(rec.get('id')==file.id){
					rec.set('percent', 0);
					rec.set('state', -3);
					rec.commit();
				}
			}
		}
		me.linkBtnEvent();
		caF(file,serverData);//上传成功后调用自定义函数
	},
	uploadProgress : function(file, bytesComplete, totalBytes){//处理进度条
		var me = this.customSettings.scope_handler;
		var percent = Math.ceil((bytesComplete / totalBytes) * 100);
		percent = percent == 100? 99 : percent;
       	var ds = me.gp.store;
		for(var i=0;i<ds.getCount();i++){
			var record =ds.getAt(i);
			if(record.get('id')==file.id){
				record.set('percent', percent);
				record.set('state', file.filestatus);
				record.commit();
			}
		}
	},
	onUploadError : function(file, errorCode, message) {
		var me = this.customSettings.scope_handler;
		me.linkBtnEvent();
		var ds = me.gp.store;
		for(var i=0;i<ds.getCount();i++){
			var rec =ds.getAt(i);
			if(rec.get('id')==file.id){
				rec.set('percent', 0);
				rec.set('state', file.filestatus);
				rec.commit();
			}
		}
	},
	onFileError : function(file,n){
		switch(n){
			case -100 : tip('待上传文件列表数量超限,不能选择!');
			break;
			case -110 : tip('文件太大,不能选择!');
			break;
			case -120 : tip('该文件大小为0,不能选择!');
			break;
			case -130 : tip('该文件类型不可以上传!');
			break;
		}
		function tip(msg){
			Ext.Msg.show({
				title : '提示',
				msg : msg,
				icon : Ext.Msg.WARNING,
				buttons :Ext.Msg.OK
			});
		}
	},
	onDiaogComplete : function(){
		var me = this.customSettings.scope_handler;
		me.linkBtnEvent();
	},
	stopUpload : function() {
		if (this.swfupload) {
			this.swfupload.uploadStopped = true;
			this.swfupload.stopUpload();
		}
	},
	deleteAll : function(){
		var ds = this.gp.store;
		for(var i=0;i<ds.getCount();i++){
			var record =ds.getAt(i);
			var file_id = record.get('id');
			this.swfupload.cancelUpload(file_id,false);			
		}
		ds.removeAll();
		this.swfupload.uploadStopped = false;
	},
	formatDelBtn : function(v){
		return "<a href='#' id='"+v+"'  style='color:blue' class='link-btn' ext:qtip='移除该文件'>移除</a>";
	},
	linkBtnEvent : function(){
		Ext.select('a.link-btn',false,this.gp.el.dom).on('click',function(o,e){
			var ds = this.gp.store;
			for(var i=0;i<ds.getCount();i++){
				var rec =ds.getAt(i);
				if(rec.get('id')==e.id){
					ds.remove(rec);
				}
			}			
			this.swfupload.cancelUpload(e.id,false);
		},this);
	}
});
Ext.reg('uploadPanel',keel.UploadPanel);

其中标识部分为自己的二次修改,下面就主要问题说明一下:

      1、uploadUrl为后台处理文件,和一般上传的处理端一样,只是后台接收文件参数由filePostName决定,这里特别的说说postParams这个参数,该参数直接加到地址上传递,包括使用addFileParam()增加的参数也一样,后台接收采用Request.QueryString[""]形式。

      2、swfupload.swf和swfupload.js的版本请使用同一版本,因为本人之前使用了czpae86实例中的swfupload.js文件,发现及及报错。

      3、后台上传成功或失败返回格式如下: Response.Write("{success:true,msg:'文档上传成功!'}"),swfupload只识别success:true或者false。

      4、本后台上传文件后将文件信息保存至数据库,其中加入PDF,SWF字段标识是否已转为该格式文档,方便后台的文档转换服务程序访问。

      5、最后效果如图:

   其中文件上传成功后调用了caF(file,serverData)函数,本函数主要作用就是在相关附件表格里加入该记录,供文件预览等操作

 

作者:kunoy
申明:作者写博是为了总结经验,和交流学习之用。
如需转载,请尽量保留此申明,并在文章页面明显位置给出原文连接。谢谢!

抱歉!评论已关闭.