Flex4/Flash多文件上傳(帶進度條)實例分享

要求

    • 必備知識

      本文要求基本瞭解 Adobe Flex編程知識和JAVA基礎知識。html

    • 開發環境

      MyEclipse10/Flash Builder4.6/Flash Player11及以上編程

    • 演示地址

      演示地址 資料下載數組

 

FLASH文件上傳和傳統的HTML文件上傳,能實現多文件上傳、大文件上傳,和上傳前預覽。安全

固然HTML5也能實現上述功能,這裏就很少說了,有時間我在作一個實例和你們分享一下。服務器

下面介紹一下 百度圖片 基於FLASH文件上傳工具截圖:ide

2014-03-07_052617

 

MultiFile Upload 上傳插件介紹:函數

2014-03-07_071021

 

官方DEMO:工具

2014-03-07_071101

 

下面是對MultiFile Upload 插件的UI自定義和代碼的翻譯:

界面:post

2014-03-07_100719

自定義UI組件:  FlashFileUpload.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
              backgroundColor="#333333" horizontalCenter="0" verticalCenter="0"
              creationComplete="initApp()">
    <fx:Declarations>
        
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            
            import com.newmediateam.fileIO.MultiFileUpload;
            
            
            import flash.media.Sound;
            import flash.media.SoundChannel;
            import flash.net.FileFilter;
            import flash.net.URLVariables;
            
            import mx.controls.Alert;
            
            import mx.core.SoundAsset;
            
            public var multiFileUpload:MultiFileUpload;
            
            // 傳送完成音樂
            [Embed(source="assets/audio/Ding.mp3")]
            public var soundClass:Class;
            public var snd:SoundAsset = new soundClass() as SoundAsset;
            public var sndChannel:SoundChannel;
            
            // 設置文件過濾器
            public var imageTypes:FileFilter = new FileFilter("Images (*.jpg; *.jpeg; *.gif; *.png)" ,"*.jpg; *.jpeg; *.gif; *.png");
            public var videoTypes:FileFilter = new FileFilter("Flash Video Files (*.flv)","*.flv");
            public var documentTypes:FileFilter = new FileFilter("Documents (*.pdf), (*.doc), (*.rtf), (*.txt)",("*.pdf; *.doc; *.rtf, *.txt"));
            
            // 將文件過濾器裝載如數組 遞給MultiFileUpload
            public var filesToFilter:Array = new Array(imageTypes,videoTypes,documentTypes);
            
            public var uploadDestination:String = "http://www.li-cheng.cn";  // 修改服務端上傳控制器
            
            public function initApp():void{
                
                var postVariables:URLVariables = new URLVariables;
                postVariables.projectID = 55;
                postVariables.test ="Hello World";    
                
                multiFileUpload = new MultiFileUpload(
                    filesDG,
                    browseBTN,
                    clearButton,
                    delButton,
                    upload_btn,
                    progressbar,
                    uploadDestination,
                    postVariables,
                    11534336,
                    filesToFilter
                );
                
                multiFileUpload.addEventListener(Event.COMPLETE,uploadsfinished);  //事件有分配
                
            }
            
            public function uploadsfinished(event:Event):void{
                
                sndChannel=snd.play();  //播放音頻文件
                
            }
            

        ]]>
    </fx:Script>
    
    
    <s:Group horizontalCenter="0" top="100"  width="708" height="408" >
        <s:BitmapImage source="@Embed('/assets/images/RasterizedItems.png')"   /> <!--背景圖片-->
        <s:SkinnableContainer horizontalCenter="0" verticalCenter="0"  width="638" height="308" skinClass="skins.SkinnableContainer">
             <s:layout>
                 <s:VerticalLayout paddingLeft="15" paddingRight="23" paddingTop="15" paddingBottom="23" />
             </s:layout>
            <!--數據列表-->
             <s:DataGrid id="filesDG" requestedRowCount="4" rowHeight="40"   width="100%" height="200"   skinClass="skins.DG" >
                <!-- <s:columns>
                     <s:ArrayList>
                         <s:GridColumn dataField="a" headerText="#" headerRenderer="components.GridHeaderRenderer"  itemRenderer="components.GridItemRenderer"></s:GridColumn>
                         <s:GridColumn dataField="b" headerText="歌曲" headerRenderer="components.GridHeaderRenderer"  itemRenderer="components.GridItemRenderer"></s:GridColumn>
                     </s:ArrayList>
                 </s:columns>-->
             </s:DataGrid>
            <s:HGroup width="65%">
                <!--進度條-->
                <mx:ProgressBar 
                    id="progressbar"
                    width="100%" 
                    labelPlacement="right"
                    barSkin="skins.ProgressBar.CustomProgressSkin"
                    trackSkin="skins.ProgressBar.CustomProgressBarTrackSkin"
                    color="0xFFFFFF"
                    minimum="0" 
                    visible="true"
                    maximum="100" 
                    label="CurrentProgress 0%" 
                    direction="right"
                    mode="manual" 
                    />
            </s:HGroup>
            <!--按鈕們-->
            <s:HGroup gap="10" paddingTop="10">
                <s:Button id="browseBTN" skinClass="skins.buttonSkin4" label="瀏覽" fontFamily="微軟雅黑"/>
                <s:Button id="upload_btn" skinClass="skins.buttonSkin5" label="上傳" fontFamily="微軟雅黑"/>
                <s:Button  id="delButton" skinClass="skins.buttonSkin6" label="移除" fontFamily="微軟雅黑"/>
                <s:Button id="clearButton" skinClass="skins.buttonSkin6" label="移除所有" fontFamily="微軟雅黑"/>
            </s:HGroup>
        </s:SkinnableContainer>
    </s:Group>
    
</s:Application>

 

主程序代碼:  MultiFileUpload.as
//    例子:
//    multiFileUpload = new MultiFileUpload(
//          filesDG,    DataGrid組件 
//          browseBTN, 瀏覽按鈕        
//          clearButton, 清楚所有    
//          delButton,     清楚選中    
//          upload_btn,     上傳按鈕    
//          progressbar,  進度條
//          "http://[Your Server Here]/MultiFileUpload/upload.cfm",   上傳地址 控制器
//          postVariables,  上傳參數     
//          350000,         最大文件大小      0 (零)值=沒有文件限制
//          filesToFilter     文件過濾數組
//           );


package com.newmediateam.fileIO {

    //倒入包
    import components.GridHeaderRenderer;
    import components.GridItemRenderer;
    
    import flash.events.*;
    import flash.net.FileFilter;
    import flash.net.FileReference;
    import flash.net.FileReferenceList;
    import flash.net.URLRequest;
    import flash.net.URLVariables;
    
    import mx.collections.ArrayCollection;
    import mx.collections.ArrayList;
    import mx.controls.Alert;
    import mx.controls.ProgressBar;
    import mx.controls.ProgressBarMode;
    import mx.core.ClassFactory;
    import mx.events.CollectionEvent;
    
    import spark.components.Button;
    import spark.components.DataGrid;
    import spark.components.gridClasses.GridColumn;

    
    
    public class MultiFileUpload {
    
        
        
        //UI 變量
        private var _datagrid:DataGrid;
        private var _browsebutton:Button;
        private var _remselbutton:Button;
        private var _remallbutton:Button;
        private var _uploadbutton:Button;
        private var _progressbar:ProgressBar;
        private var _testButton:Button;

        //DataGrid 列
        private var _nameColumn:GridColumn;
        private var _typeColumn:GridColumn;
        private var _sizeColumn:GridColumn;
        private var _creationDate:GridColumn;
        private var _modificationDate:GridColumn;
        private var _progressColumn:GridColumn;
        private var _columns:ArrayList;
        
        // 文件參考變量
        [Bindable]
        private var _files:ArrayCollection;
        private var _fileref:FileReferenceList  //FileReferenceList 類提供了讓用戶選擇一個或多個要上載的文件的方法。
        private var _file:FileReference;  //FileReference 類提供了在用戶計算機和服務器之間上載和下載文件的方法
        private var _uploadURL:URLRequest;
        private var  _totalbytes:Number;
        
        // 文件過濾數組
        private var _filefilter:Array;

        //配置變量
        private var _url:String; //  文件上傳URL
        private var _maxFileSize:Number; //容許上次的最大文件大小 單位字節
        private var _variables:URLVariables; // 上傳變量 相似 ?a=hello&b=world
        
        //構造器  
        public function MultiFileUpload(
                                        dataGrid:DataGrid,
                                        browseButton:Button,
                                        removeAllButton:Button,
                                        removeSelectedButton:Button,
                                        uploadButton:Button,
                                        progressBar:ProgressBar,
                                        url:String,
                                        variables:URLVariables,
                                        maxFileSize:Number,
                                        filter:Array
                                        ){
            _datagrid = dataGrid;
            _browsebutton = browseButton;
            _remallbutton = removeAllButton;
            _remselbutton = removeSelectedButton;            
            _uploadbutton = uploadButton;
            _url = url;
            _progressbar = progressBar;
            _variables = variables;
            _maxFileSize = maxFileSize;
            _filefilter = filter;
            init();   //調用初始化話函數
        }
        
        //初始化函數
        private function init():void{
            
            // 設置文件 ArrayCollection 和  文件處理變量
            _files = new ArrayCollection();
            _fileref = new FileReferenceList;
            _file = new FileReference;
            
            // 設置總字節數
            _totalbytes = 0;
            
            // 給UI組件監聽事件
            _browsebutton.addEventListener(MouseEvent.CLICK, browseFiles);
            _uploadbutton.addEventListener(MouseEvent.CLICK,uploadFiles);
            _remallbutton.addEventListener(MouseEvent.CLICK,clearFileCue);
            _remselbutton.addEventListener(MouseEvent.CLICK,removeSelectedFileFromCue);
            _fileref.addEventListener(Event.SELECT, selectHandler);
            _files.addEventListener(CollectionEvent.COLLECTION_CHANGE,popDataGrid);  //集合數據變化是監聽此函數
            
            // 設置進度條參數
            _progressbar.mode = "manual"; // 指定用於更新進度欄的方法。
            _progressbar.label = "";
            
            //設置按鈕組件
            _uploadbutton.enabled = false;
            _remselbutton.enabled = false;
            _remallbutton.enabled = false;
            
            
            // 設置 DataGrid 控件
            _nameColumn = new GridColumn;
            _typeColumn = new GridColumn;
            _sizeColumn = new GridColumn;
                
            _nameColumn.dataField = "name";
            _nameColumn.headerText= "文件";
            _nameColumn.headerRenderer=new ClassFactory(GridHeaderRenderer);
            
            _typeColumn.dataField = "type";
            _typeColumn.headerText = "類型";
            _typeColumn.width = 80;
            _typeColumn.headerRenderer=new ClassFactory(GridHeaderRenderer);
            
            _sizeColumn.dataField = "size";
            _sizeColumn.headerText = "文件大小";
            _sizeColumn.labelFunction = bytesToKilobytes as Function; //Label處理函數
            _sizeColumn.width = 150;
            _sizeColumn.headerRenderer=new ClassFactory(GridHeaderRenderer);
            
            _columns = new ArrayList([_nameColumn,_typeColumn,_sizeColumn]);
            _datagrid.columns=_columns;
            
            
            _datagrid.sortableColumns = false; //排序
            _datagrid.dataProvider = _files;  //數據綁定
          
            
            // 設置URL請求對象和地址
            _uploadURL = new URLRequest;
            _uploadURL.url = _url;
            _uploadURL.method = "POST";  //設置請求方式     能夠爲POST和GET  ..
            
            _uploadURL.data = _variables; //變量
            _uploadURL.contentType = "multipart/form-data"; //請求類型聲明 若是要上傳二進制數據這個必須 
            
            
        }
        
        /********************************************************
        *     私有方法                                                                                               *
        ********************************************************/
        
        
        //  流量文件  多文件流量
        private function browseFiles(event:Event):void{                    
                _fileref.browse(_filefilter);               
       }

        // 上傳文件
        private function uploadFiles(event:Event):void{
           
            if (_files.length > 0){
                _file = FileReference(_files.getItemAt(0));    
                _file.addEventListener(Event.OPEN, openHandler);  //前置操做
                _file.addEventListener(ProgressEvent.PROGRESS, progressHandler);
                _file.addEventListener(Event.COMPLETE, completeHandler);
                _file.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);//當對 FileReference.upload() 或 FileReference.download() 方法的調用嘗試將文件上載到調用方安全沙箱外部的服務器,或是從調用方安全沙箱外部的服務器上下載文件時進行調度。
                _file.addEventListener(HTTPStatusEvent.HTTP_STATUS,httpStatusHandler);//當上載失敗而且存在可用來描述失敗的 HTTP 狀態代碼時調度。
                _file.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler);//當上載或下載失敗時調度。
                _file.upload(_uploadURL);
                 setupCancelButton(true);
            }
        }
        
        // 刪除選定的文件
        private function removeSelectedFileFromCue(event:Event):void{
           
            if (_datagrid.selectedIndex >= 0){
                    _files.removeItemAt( _datagrid.selectedIndex);
            }
        }


         //  刪除所有文件
        private function clearFileCue(event:Event):void{
            _nameColumn.itemRenderer=null;
            _typeColumn.itemRenderer=null;
            _sizeColumn.itemRenderer=null;
            _files.removeAll();
        }
        
        // 取消當前文件上傳
        private function cancelFileIO(event:Event):void{
            
            _file.cancel();
            setupCancelButton(false);
            checkCue();
            
        }    
    
       


        //文件類型列  label處理函數
        private function bytesToKilobytes(data:Object,blank:Object):String {
            var kilobytes:String;
            kilobytes = String(Math.round(data.size/ 1024)) + ' kb';
            return kilobytes
        }
        
        
       
        // 設置進度條Labe值
        private function getByteCount():void{
            var i:int;
            _totalbytes = 0;
                for(i=0;i < _files.length;i++){
                _totalbytes +=  _files[i].size;
                }
            _progressbar.label = "文件: "+  _files.length+ "大小: " + Math.round(_totalbytes/1024) + " kb"
        }        
        
       
        //檢查文件不超過maxFileSize爲|若是_maxFileSize == 0沒有文件限制設置
        private function checkFileSize(filesize:Number):Boolean{
      
            var r:Boolean = false;
                //if  filesize greater then _maxFileSize
                if (filesize > _maxFileSize){
                    r = false;
                    trace("false");
                    }else if (filesize <= _maxFileSize){
                    r = true;
                    trace("true");
                }
                
                if (_maxFileSize == 0){
                r = true;
                }
           
            return r;
        }
        
      
        // 從新設置進度條
        private function resetProgressBar():void{
        
                  _progressbar.label = "";
                 _progressbar.maximum = 0;
                 _progressbar.minimum = 0;
        }
        
        // reset form item elements 重置全部的元素
        private function resetForm():void{
            _uploadbutton.enabled = false;
            _uploadbutton.addEventListener(MouseEvent.CLICK,uploadFiles);
            _uploadbutton.label = "上傳";
            _progressbar.maximum = 0;
            _totalbytes = 0;
            _progressbar.label = "";
            _remselbutton.enabled = false;
            _remallbutton.enabled = false;
            _browsebutton.enabled = true;
        }
       
        
        //每當_FILES的ArrayCollection改變這個函數被調用,以確保數據網格的數據的一致
        private function popDataGrid(event:CollectionEvent):void{                
            getByteCount();
            checkCue();
        }
        
       // enable or disable upload and remove controls based on files in the cue;   
        //啓用上傳和清楚按鈕
        private function checkCue():void{
             if (_files.length > 0){
                _uploadbutton.enabled = true;
                _remselbutton.enabled = true;
                _remallbutton.enabled = true;            
             }else{
                resetProgressBar();
                _uploadbutton.enabled = false;     
             }    
        }

        // toggle upload button label and function to trigger file uploading or upload cancelling
        // 上傳按鈕和取消按鈕的切換 和功能的切換
        private function setupCancelButton(x:Boolean):void{
            if (x == true){
                _uploadbutton.label = "取消";
                _browsebutton.enabled = false;
                _remselbutton.enabled = false;
                _remallbutton.enabled = false;
                _uploadbutton.addEventListener(MouseEvent.CLICK,cancelFileIO);        
            }else if (x == false){
                _uploadbutton.removeEventListener(MouseEvent.CLICK,cancelFileIO);
                 resetForm();
            }
        }
        

       /*********************************************************
       *  File IO Event Handlers                                *
       *********************************************************/
      
        //  called after user selected files form the browse dialouge box.
        //  文件被選中後執行的響應函數
        private function selectHandler(event:Event):void {
            var i:int;
            var msg:String ="";
            var dl:Array = [];                          
                for (i=0;i < event.currentTarget.fileList.length; i ++){
                    if (checkFileSize(event.currentTarget.fileList[i].size)){
                    _files.addItem(event.currentTarget.fileList[i]);
                    trace("under size " + event.currentTarget.fileList[i].size);
                    }  else {
                    dl.push(event.currentTarget.fileList[i]);
                    trace(event.currentTarget.fileList[i].name + " too large");
                    }
                    
                    
                    _nameColumn.itemRenderer=new ClassFactory(GridItemRenderer);
                    _typeColumn.itemRenderer=new ClassFactory(GridItemRenderer);
                    _sizeColumn.itemRenderer=new ClassFactory(GridItemRenderer);
                    _sizeColumn.labelFunction = bytesToKilobytes as Function; //Label處理函數
                    
                }                
                if (dl.length > 0){
                    for (i=0;i<dl.length;i++){
                    msg += String(dl[i].name + " 文件過大. \n");
                    }
                    mx.controls.Alert.show(msg + "文件最大爲: " + Math.round(_maxFileSize / 1024) + " kb","文件過大",4,null).clipContent;
                }        
        }        
        
    
        // 文件被打開  上傳以前的響應函數
        private function openHandler(event:Event):void{
            trace('openHandler triggered');
            _files;
        }
        
      
          //文件上傳被上傳的每一個文件的過程當中調用|咱們用這個來養活進度條的數據
        private function progressHandler(event:ProgressEvent):void {        
            _progressbar.setProgress(event.bytesLoaded,event.bytesTotal);  //設置進度條的狀態
            _progressbar.label = "Uploading " + Math.round(event.bytesLoaded / 1024) + " kb of " + Math.round(event.bytesTotal / 1024) + " kb " + (_files.length - 1) + "剩餘";
        }

      
        //所謂的後一個文件已被successully上傳|咱們利用這一點來檢查是否有任何文件留下來上傳和如何處理它
        //上傳完成
        private function completeHandler(event:Event):void{
          
            _files.removeItemAt(0); //移除集合中的第0號元素
            if (_files.length > 0){
                _totalbytes = 0;
                uploadFiles(null);
            }else{
                setupCancelButton(false);
                 _progressbar.label = "上傳完成";
                 var uploadCompleted:Event = new Event(Event.COMPLETE);  //完成時建立一個事件 
                 
                dispatchEvent(uploadCompleted); //把事件分配出去
            }
        }    
          
      
        private function ioErrorHandler(event:IOErrorEvent):void{
            //trace('And IO Error has occured:' +  event);
            mx.controls.Alert.show(String(event),"ioError",0);
        }    
      
        private function securityErrorHandler(event:SecurityErrorEvent):void{
            mx.controls.Alert.show(String(event),"Security Error",0);
        }
        
       
        private function cancelHandler(event:Event):void{
            trace('cancelled');
        }
        
        private function httpStatusHandler(event:HTTPStatusEvent):void {
            if (event.status != 200){
                mx.controls.Alert.show(String(event),"Error",0);
            }
        }

        
    }
}

 

演示地址: http://www.li-cheng.cn/demo/FlashFileUpload/FlashFileUpload.htmlflex

資料下載:    http://pan.baidu.com/share/link?shareid=1217875474&uk=1545675865

做者: Li-Cheng
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
相關文章
相關標籤/搜索