Flex4/Flash多文件上传(带进度条)实例分享

要求

    • 必备知识

      本文要求基本了解 Adobe Flex编程知识和JAVA基础知识。

    • 开发环境

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

    • 演示地址

      演示地址 资料下载

 

FLASH文件上传和传统的HTML文件上传,能实现多文件上传、大文件上传,和上传前预览。

当然HTML5也能实现上述功能,这里就不多说了,有时间我在做一个实例和大家分享一下。

下面介绍一下 百度图片 基于FLASH文件上传工具截图:

2014-03-07_052617

 

MultiFile Upload 上传插件介绍:

2014-03-07_071021

 

官方DEMO:

2014-03-07_071101

 

下面是对MultiFile Upload 插件的UI自定义和代码的翻译:

界面:

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.html

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

作者:Li-Cheng
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2014-03-07 10:24  Li-Cheng  阅读(2594)  评论(6编辑  收藏  举报