RIA工作室,商业智能(David liu)

Flex 3、Adobe AIR、Coldfusion、Ajax、Java&C#,Eclipse、.Net,BI

原创 Flex 2 扩展DataGrid实现行与列的自动合计收藏

新一篇: 第一个FLEX2项目终于见到希望,终于要结束了,有点时间写一点心得 | 旧一篇: 提高客户体验的RIA开发技术

      在一个项目当中很多地方用到DataGrid,而且需要显示合计行与合计列,所以想办法扩展 了一下Flex 2 的DataGrid,覆盖了dataProvider 的set方法与columns的set方法,另外加入了计算合计数的方法,当然现在还没有写的那么细,不过与大家共享一下,希望有兴趣的继续改进这个组件,下面附上代码,未经同意,禁止转载:

<?xml version="1.0" encoding="utf-8"?>
<mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" columnStretch="onColumnStrech(event)" headerShift="onHeaderShift(event)" sortableColumns="false">
    <mx:Script>
        <![CDATA[
            import mx.events.IndexChangedEvent;
            import mx.events.DataGridEvent;
            import mx.controls.dataGridClasses.DataGridColumn;
            import mx.core.Application;
            import mx.controls.TextInput;
            import mx.core.UIComponent;
            import mx.containers.HBox;
            import mx.utils.ArrayUtil;
            import mx.utils.ObjectUtil;
            import mx.collections.ArrayCollection;
            import mx.validators.NumberValidator;
            import mx.events.DataGridEventReason;
            
            private var totaldg : DataGrid ;
            private var _showRowTotal : Boolean = false;
            private var _showColumnTotal : Boolean = false;
            public var canShiftHeaders : Boolean = false;
            public function set showRowTotal(value:Boolean):void
            {
                this._showRowTotal = value;
            }
            public function get showRowTotal():Boolean
            {
                return this._showRowTotal;
            }
            public function set showColumnTotal(value:Boolean):void
            {
                this._showColumnTotal = value;
            }
            public function get showColumnTotal():Boolean
            {
                return this._showColumnTotal;
            }
            override public function set columns(value:Array):void
            {
                if(_showColumnTotal && value is Array)
                {
                    if(value)
                    {
                        var totalcol : DataGridColumn = new DataGridColumn();
                        totalcol.dataField = "vtotal";
                        totalcol.headerText = "合计";
                        totalcol.setStyle("textAlign","right");
                        totalcol.width = 100;
                        (value as Array).push(totalcol);
                    }
                }
                getTotalDG().columns = value;
                super.columns = value;
            }
     
       /**
         *  @private
         */
        override public function set dataProvider(value:Object):void
        {
            var objhtotal : Object = new Object();
            if(value is Array)
            {
                var acc : ArrayCollection = new ArrayCollection(value as Array);
                var objvtotal : Object = new Object();
                var columncount :int = 0;
                var alltotal : Number = 0;
                for each(var row : Object in acc)
                {
                    var n : Number = 0;
                    var colnum : int = 0;
                    for(var colvalue:Object in row)
                    {
                        
                        if(!isNaN(Number(row[colvalue])) && _showRowTotal && colvalue !="year" && colvalue !="yearperiod" && colvalue !="period" )
                        {
                            if(isNaN(objvtotal[colvalue]))
                            {
                                objvtotal[colvalue]=Number(row[colvalue]);
                            }
                            else
                            {
                                objvtotal[colvalue] += Number(row[colvalue]);
                            }
                            
                            n += Number(row[colvalue]);
                        }
                        else if(_showRowTotal)
                        {
                            if(objvtotal[colvalue]==undefined)
                            {
                                objvtotal[colvalue]="";
                            }
                            else
                            {
                                objvtotal[colvalue]="";
                            }
                        }
                        colnum++;
                        columncount = colnum;
                    }
                    if(_showColumnTotal)
                    {
                        row["vtotal"] = n;
                    }
                    if(_showRowTotal)
                    {
                        alltotal += n;
                        objvtotal["vtotal"] = alltotal;
                    }
                }
                getTotalDG().dataProvider = ArrayUtil.toArray(objvtotal);
                if(_showRowTotal && parent.getChildByName("totaldg")==null)
                  parent.addChild(getTotalDG());
            }
            super.dataProvider = value;
        }
        
        private function getTotalDG():DataGrid
        {
            if(totaldg == null)
            {
                totaldg = new DataGrid();
                totaldg.name = "totaldg";
            }
            totaldg.height = 22;
            totaldg.percentWidth = 100;
            totaldg.showHeaders = false;
            return totaldg;
        }
        override protected  function collectionChangeHandler(event:Event):void
        {
            //trace(event.target+"collectionChangeHandler");
            super.collectionChangeHandler(event);
            //this.willTrigger("dataChange");
        }  
        private function onColumnStrech(event:DataGridEvent):void
        {
            getTotalDG().columns[event.columnIndex].width = columns[event.columnIndex].width;
        }
        private function onHeaderShift(event:IndexChangedEvent):void
        {
            if(!canShiftHeaders)
              event.preventDefault();
          else
          {
              
          }
            var newpos : int = event.newIndex;
            var oldpos : int = event.oldIndex;
            var cols : Array = getTotalDG().columns;
            var c : Object = cols[oldpos];
            cols[oldpos] = cols[newpos];
            cols[newpos] = c;
            getTotalDG().columns = cols;
            //trace(event.newIndex,event.oldIndex,event.relatedObject);
            
        }
        ]]>
    </mx:Script>
</mx:DataGrid>

另外还有一个引用该组件的另一个组件,你可以从这里看到如何使用这个扩展的UIDataGrid组件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" xmlns:ns1="jl.ui.pub.beans.*" creationPolicy="all" verticalGap="0">
<mx:Script>
    <![CDATA[
        import mx.controls.DataGrid;
        import mx.utils.UIDUtil;
        import com.adobe.images.JPGEncoder;
        import mx.managers.CursorManager;
        import jl.utils.excel.DataGrid2ExcelUtil;
        import mx.rpc.events.ResultEvent;
        [Bindable]
        private var _dataArray : Array;
        [Bindable]
        private var _mycols : Array;
        [Bindable]
        private var _showRowTotal : Boolean = false;
        [Bindable]
        private var _showColumnTotal : Boolean = false;
        [Bindable]
        public var lbFunction : Function; 
        [Bindable]
        public var allowMultipleSelection : Boolean = true;
        [Bindable]
        public var editable : Boolean;
        [Bindable]
        public var canShiftHeaders : Boolean = false;
        private var toolMenu  : ContextMenu;
        public function set showRowTotal(value:Boolean):void
        {
            this._showRowTotal = value;
        }
        public function get showRowTotal():Boolean
        {
            return this._showRowTotal;
        }
        public function set showColumnTotal(value:Boolean):void
        {
            this._showColumnTotal = value;
        }
        public function get showColumnTotal():Boolean
        {
            return this._showColumnTotal;
        }
        public function set dataArray(value:Array):void
        {
            this._dataArray = value;
            //uidg.dataProvider = value;
        }
        public function get dataArray():Array
        {
            return this._dataArray;
        }
        public function set mycols(value:Array):void
        {
            this._mycols = value;
        }
        public function get mycos():Array
        {
            return this._mycols;
        }
        private function getToolMenu():ContextMenu
        {
            if(toolMenu == null)
            {
                toolMenu = new ContextMenu();
                //toolMenu.addEventListener(ContextMenuEvent.MENU_SELECT, toolmenuSelectHandler);
                toolMenu.hideBuiltInItems();
                var menuItem1 : ContextMenuItem = new ContextMenuItem("输出到Excel电子表格");
                menuItem1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
                var menuItem2 : ContextMenuItem = new ContextMenuItem("另存为图片");
                menuItem2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
                toolMenu.customItems.push(menuItem1,menuItem2);
            }
            return toolMenu;
        }
        private function menuItemSelectHandler(event:ContextMenuEvent):void {
        if(event.target.caption == "另存为图片")
        {
            var target : DisplayObject = event.contextMenuOwner as DisplayObject;
            doSave(target);
        }
        else if(event.target.caption == "输出到Excel电子表格")
        {
            var target1 : DisplayObject = event.contextMenuOwner as DisplayObject;
            if(target1 && target1 is DataGrid)
            {
                var dg2excel : DataGrid2ExcelUtil = new DataGrid2ExcelUtil();
                dg2excel.copyAndOpen(target1 as DataGrid);
            }
        }
    }
    
    private function doSave(target : DisplayObject):void
        {
            CursorManager.setBusyCursor();
            var bd:BitmapData = getBitmapData(target);
            CursorManager.removeBusyCursor();
            var jpe : JPGEncoder = new JPGEncoder(100);
            //var bty2 : ByteArray = PNGEnc.encode(bd);
            var bty : ByteArray = jpe.encode(bd);
            ro.doUpload(bty,UIDUtil.createUID()+".jpg");
        }
        /**********************************************************
           This function is the real "meat" of this code snippet.
          **********************************************************/
        private function getBitmapData( target : DisplayObject ) : BitmapData
        {
           var bd : BitmapData = new BitmapData( target.width, target.height );
           var m : Matrix = new Matrix();
           bd.draw( target, m );
           return bd;
        }
        private function handleResult(event:ResultEvent):void
        {
            var fileRef : FileReference = new FileReference();
            var u:URLRequest = new URLRequest("uploadedfile/images/"+event.result);
            fileRef.download(u,"默认文件名称.jpg");
            fileRef.addEventListener(ProgressEvent.PROGRESS,
            function upProgress(event : ProgressEvent):void
            {
                trace("已经下载"+event.bytesLoaded);
            });
            fileRef.addEventListener(Event.COMPLETE,
            function onFinished(event : Event):void
            {
                trace("文件下载完毕");
            });
            fileRef.addEventListener(IOErrorEvent.IO_ERROR,
            function onIOError(event : IOErrorEvent):void
            {
                trace("文件下载错误,请检查网络连接并重试");
            });
            //navigateToURL(u,"_blank");
        }
    ]]>
</mx:Script>
<mx:RemoteObject id="ro" destination="UploadImage-ro"
        result="handleResult(event)" showBusyCursor="true"/>
    <ns1:UIDataGrid id="uidg" labelFunction="{lbFunction}" dataProvider="{_dataArray}" columns="{_mycols}" showColumnTotal="{_showColumnTotal}" showRowTotal="{_showRowTotal}" allowMultipleSelection="{allowMultipleSelection}" editable="{editable}" canShiftHeaders="false" contextMenu="{getToolMenu()}"/>
</mx:VBox>

生成电子表格的as代码:

package jl.utils.excel
{
 import mx.controls.DataGrid;
 import flash.system.System;
 import flash.external.ExternalInterface;
 import flash.events.KeyboardEvent;
 import mx.managers.CursorManager;
 import mx.collections.ArrayCollection;
 
 public class DataGrid2ExcelUtil
 {
  public function DataGrid2ExcelUtil():void
  {
   trace("生成DataGrid2ExcelUtil新实例");
  }
  public function doCopy(dg : DataGrid):void
  {
   var font : Object = dg.getStyle('fontFamily');
   var size : Object = dg.getStyle('fontSize');
   var hcolor : Object ;
   if(dg.getStyle("headerColor") != undefined)
     hcolor = [dg.getStyle("headerColor")];
   else
     hcolor = dg.getStyle("headerColors");
   var str:String = '<html><body><table width="'+dg.width+'"><thead><tr width="'+         dg.width+'" style="background-color:#' +Number((hcolor[0])).toString(16)+'">';
   for(var i1:Number=0;i1<dg.columns.length;i1++)
   {
       var colors1 : Object = dg.getStyle("themeColor");
       var style : String = 'style="font-family:'+font+';font-size:'+size+'pt;"';
    if(dg.columns[i1].headerText != undefined)
    {
     str+="<th "+style+">"+dg.columns[i1].headerText+"</th>";
    }
    else
    {
     str+= "<th "+style+">"+dg.columns[i1].dataField+"</th>";
    }
   }
   str += "</tr></thead><tbody>";
   var colors : Object = dg.getStyle("alternatingItemColors");
   var dgdata : ArrayCollection;
   var dataobj : Object = dg.dataProvider;
   if(dataobj is ArrayCollection)
   {
    dgdata = dataobj as ArrayCollection;
   }
   else if(dataobj is Array)
   {
    dgdata = new ArrayCollection(dataobj as Array);
   }
   for(var j:Number=0;j<dgdata.length;j++)
   {
    str+="<tr width=\""+Math.ceil(dg.width)+"\" style='background-color:#" +Number((colors[j%colors.length])).toString(16)+"'>";
    var style1 : String = 'style="font-family:'+font+';font-size:'+size+'pt;"';
    for(var i:Number=0;i<dg.columns.length;i++)
    {
     if(dgdata.getItemAt(j) != "undefined" && dgdata.getItemAt(j) != null)
      if(dg.columns[i].labelFunction != undefined)
       str += "<td width=\""+Math.ceil(dg.columns[i].width)+"\" "+style1+">"+dg.columns[i].labelFunction(dgdata.getItemAt(j),dg.columns[i]..dataField)+"</td>";
      else
       str += "<td width=\""+Math.ceil(dg.columns[i].width)+"\" "+style1+">"+dgdata.getItemAt(j)[dg.columns[i].dataField]+"</td>";
    }
    str += "</tr>";
   }
   str+="</tbody></table></body></html>";
   System.setClipboard(str);
  }
  public function copyAndOpen(grid:DataGrid):void
  {
    doCopy(grid);//
    trace("生成DataGrid表格内容并按HTML字符格式复制到系统剪贴板完毕");
    ExternalInterface.call("openExcel");
    trace("输出到excel电子表格式完毕");
  }
 }
}

 

生成电子表格的js代码:

function openExcel()
{
 try
 {
  if(excel == null)
  { 
    excel = new ActiveXObject("Excel.Application");
  }
  var workbook = excel.Workbooks.Add();
  workbook.Activate();
  var worksheet = workbook.Worksheets("Sheet1");
  worksheet.Activate();
  worksheet.Paste();
  excel.visible=true;
 }
 catch(exception)
 {
  window.alert("Now you may Paste into an Excel SpreadSheet");
 }
}

发表于 @ 2007年04月21日 12:54:00|评论(loading...)|收藏

新一篇: 第一个FLEX2项目终于见到希望,终于要结束了,有点时间写一点心得 | 旧一篇: 提高客户体验的RIA开发技术

评论

#yaksea 发表于2007-10-31 01:19:49  IP: 117.28.234.*
你好,jl.utils.excel.DataGrid2ExcelUtil是你自己写的吗,可否告知如何实现
发表评论  


登录
Csdn Blog version 3.1a
Copyright © David Liu