1. 程式人生 > >Extjs上傳附件實戰開發,實現批量上傳及線上預覽功能(二)

Extjs上傳附件實戰開發,實現批量上傳及線上預覽功能(二)

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 申明:作者寫博是為了總結經驗,和交流學習之用。
如需轉載,請儘量保留此申明,並在文章頁面明顯位置給出原文連線。謝謝!

相關推薦

Extjs附件實戰開發實現批量線上功能

SWFUpload的使用:         SWFUpload採用czpae86的UploadPanel二次開發,在此鳴謝。         SWFUpload下載最新版本swfupload.swf.v2.5.0.beta3.2.zip,你會發現資料夾裡只有swfuploa

不帶插件 自己寫js實現批量文件進度顯示

批量上傳 發的 xhr string () .cn tom 需要 pen 今天接受項目中要完成文件批量上傳文件而且還要顯示上傳進度,一開始覺得這個應該不是很麻煩,當我在做的時候遇到了很多問題,很頭疼啊。 不過看了別人寫的代碼,自己也測試過,發現網上好多都存在一些問題,並不是

不帶外掛 自己寫js實現批量檔案進度顯示

今天接受專案中要完成檔案批量上傳檔案而且還要顯示上傳進度,一開始覺得這個應該不是很麻煩,當我在做的時候遇到了很多問題,很頭疼啊。 不過看了別人寫的程式碼,自己也測試過,發現網上好多都存在一些問題,並不是自己想要的。然後自己查閱各種資料,經過自己總結,最終完成了這個功能。

用原生JS實現多張圖片功能相容IE8

最近需要做一個圖片上傳預覽的功能(相容IE8-11、chrome、firefox等瀏覽器),網上現有的檔案上傳元件(如webuploader)總是會遇到一些相容性問題。於是我參考了一些博文(連結找不到了⊙o⊙…),自己用原生JS寫了一個支援多張圖片上傳預覽功能的Demo 先通過最終效果看一下功能:

Netty遊戲伺服器實戰開發(11):Spring+mybatis 手寫分庫分表策略

在大型網路遊戲中,傳統的遊戲伺服器無法滿足效能上的需求。所以有了分散式和微服務新起,在傳統web伺服器中,我們儲存使用者等資訊基本都是利用一張單表搞定,但是在遊戲伺服器中,由於要求比較高,我們不能存在大表操作,即分庫分表策略。在以前的文章中有關介紹分庫分表的,下面我們來實戰一下,首先我們

前端開發框架總結之利用Jtopo實現網路拓撲功能

                    前端開發框架總結之利用Jtopo實現網路拓撲功能(二) 上文我們講了一些拓撲結點生成的實際場景設計和實現思路以及一些關鍵技術細節。本文我們繼續我們的拓撲管理

開發實戰:基於maven+SSM+EasyUI的高校共享汽車管理系統

基於maven+SSM+EasyUI的高校共享汽車管理系統   繼上一篇 專案需求分析之後,接下來就是資料庫設計了。      作為一個管理系統,各種資訊表是必不可少的了。一般來說,專案都是開發之前先確定資料庫有哪些表的,但是因為我這個個人思考的畢業設計,

【Ceph】基於Tornado的Ceph檔案與下載線上

概述 用tornado作為http伺服器 在處理post/get請求的方法中,呼叫librados(python)介面實現讀寫 設定Content-disposition中為inline則線上瀏覽,

使用flexpaper實現線上功能遇到的flash快取問題的解放方案

本專案使用的是本地目錄對映為伺服器相對路徑,故預覽頁面時讀取的flash與專案不再同一碟符中,若更改flash檔案後,預覽還是隻顯示之前的舊檔案,一番搜尋後找到了解決方案,flexpaper 的官方demo中,有一個和java相關的demo,其中給出了一些方法,整理後使用如

Android開發實現滑動RecyclerView,浮動按鈕的顯示和隱藏

本篇部落格,主要講解了滑動RecyclerView實現FloatingActionButton的顯示和隱藏的動畫。 -------------------------------分割線----------------------------- 效果圖展示: -------

用Maven整合SpringMVC+Spring+Hibernate 框架實現簡單的插入資料庫資料功能

前一篇寫的有些多,大家先看前一篇,傳送門 具體的資源已將上傳到資源了。 上文我們直接搭建前的準備和資源配置都寫好了,下面進入具體程式碼編寫。承接上文的小3 3、我習慣建立介面,這樣對整個專案感覺更合理。 (1.)建立IBaseService(業務邏輯層,有的習慣寫成Ba

(詳細)Hibernate查詢技術Query、Session、CriteriaHibernate的三種狀態Hibernate集合struts2實現登入功能

Hibernate中提供了三種查詢方式: 1)Session的查詢:按主鍵查詢查詢,方法為get或load 2)Query的查詢:使用HQL語句或SQL語句完成查詢 3)Criteria的查詢:通過方法和類中屬性的關係,來設定查詢條件,完成查詢。 Session中get和load方法的區別? 1)  如果

springboot 實現攔截器許可權過濾以及用攔截器實現操作日誌功能

接上文 繼承WebMvcConfigurerAdapter 類,新增 上文寫的攔截類 具體程式碼如下: package com.hcmony.web.interceptor; import org

記錄一下實現各種文檔在線功能

mem util oid vat filename sys vax xls trac 首先是通過方法把對應的文檔編譯成為對應的pdf文件,然後再瀏覽器打開對應的pdf文件。從而實現預覽效果; 但要註意的是,預覽打開的url存在中文問題,我這邊始終存在因為轉義,而提示無法找

酷播V4更新了支持PC端和移動端的視頻功能收費視頻功能

href img 收費 oss www. bsp com 蘋果 免費 感覺要變天了,灰蒙蒙的。好久沒有下雨了... [酷播V4]永久免費的酷播V4,更新了html5和flash播放器的優先級選項,效果: 效果演示:http://www.cuplayer.com/CuP

手把手嘴對嘴講解UCOSII嵌入式操作系統的初始化過程

同學 save sam 嵌入式操作系統 相關信息 trie allow 狀態 cos 本章重點講解空閑任務的建立過程。 任務建立函數定義如下: 1 INT8U OSTaskCreate (void (*task)(void *p_arg), 2

基於公有雲平臺實現直播、點播小視頻功能

騰訊 去除 使用 商業 png wowza 技術分享 傳感器 都是 呵呵,上一節不知道怎麽的就開始扯起了電視的發展,不過確實是勾起了我童年的回憶,這節我們正式進入正題,先說說直播。直播這個詞看到以後,讓我們想到的是什麽?其實感覺也沒什麽,因為已經很普及,是否更多的是想到了直

React第一階段實戰分析--評論功能

處理使用者輸入 首先先寫出html結構以及樣式 class CommentInput extends React.Component{ render(){ return ( <div className='comme

PHP+MySQL實現留言板功能

上次我們做了登陸註冊頁面的前端設計,這一節我們實現登陸和註冊 結合上次的登陸註冊頁面,這次我們先實現註冊,那麼,我們就要先寫註冊頁面的後端處理程式碼。我們將其命名為:doregister.php  程式碼如下。 <?php require_once "connet.php"; r

Xamarin實現將圖片設定為啟動頁——Xamarin.forms

其實設定啟動頁很簡單,只是我在做的時候,踩了一些坑,就走了一些彎路。 我知道大家一點開這些部落格就想看到原始碼,在我搭建環境給的demo裡面就有一個splash的demo,多個app的demo免費相送,傳送門:https://blog.csdn.net/qq_41647999/article