Flex动态DataGrid 一

               

     相信每个开发过flex的用户都用过datagrid,但是传统的datagrid有很多弱点,例如有一个弱点就是比较难在内存动态生成头部的标题,如果您只是一个传入一个未知的二维表结构,希望它动态显示就让人感觉无能为力了,所以为力完善相关的设计,我尝试用xml动态定义了标题,如果大家喜欢这个代码请给我留个支持哦。

datagrid代码

<?xml version="1.0" encoding="utf-8"?><mx:DataGrid xmlns:fx="http://ns.adobe.com/mxml/2009"     xmlns:s="library://ns.adobe.com/flex/spark"     xmlns:mx="library://ns.adobe.com/flex/mx"     creationComplete="datagrid_creationCompleteHandler(event)"> <!-- type="image/html/external" --> <fx:Declarations>  <fx:XML id="titleXml" xmlns="">   <nodes>    <node width="20">     <ename>key1</ename>     <cname>key1</cname>    </node>    <node width="30%">     <ename>key2</ename>     <cname>key2</cname>    </node>   </nodes>  </fx:XML>  <fx:XML id="xml" xmlns="">   <nodes>    <node>     <key1>value1</key1>     <key2>value2</key2>    </node>   </nodes>  </fx:XML> </fx:Declarations> <fx:Script>  <!--[CDATA[   import com.shine.framework.DBUtil.model.DBModel;   import com.shine.framework.core.model.BaseXmlModel;   import com.shine.framework.core.model.XmlModel;   import com.shine.framework.core.util.ArrayMap;   import com.shine.framework.core.util.DataUtil;      import mx.controls.Alert;   import mx.controls.dataGridClasses.DataGridColumn;   import mx.events.FlexEvent;      import spark.components.TextArea;      //是否允许下载文件   public var downloadPolicy:String="off";      //单元格类型   public var itemRendererClass:ClassFactory=null;   //初始化   private function datagrid_creationCompleteHandler(event:FlexEvent):void   {    var titleArray:Array=new Array;        if(titleXml!=null){     for each (var xml:XML in titleXml.children())     {      var dataGridColumn:DataGridColumn=new DataGridColumn;      dataGridColumn.dataField=XML(xml.ename).toString();      dataGridColumn.headerText=XML(xml.cname).toString();      if(xml.@width!=null&&String(xml.@width).length!=0){       if(String(xml.@width).indexOf("%")!=-1){        dataGridColumn.width=this.width*int(DataUtil.StringReplaceAll(String(xml.@width),"%",""));       }else{        dataGridColumn.width=int(xml.@width);       }      }            if(String(xml.@type)==null){             }else if(String(xml.@type)=="image"){       dataGridColumn.itemRenderer=new ClassFactory(com.shine.framework.core.view.ImageDataGridRender);      }else if(String(xml.@type)=="html"){       dataGridColumn.itemRenderer=new ClassFactory(com.shine.framework.core.view.HTMLDataGridRender);      }else if(String(xml.@type)=="external"){       if(itemRendererClass!=null)        dataGridColumn.itemRenderer=itemRendererClass;      }            titleArray.push(dataGridColumn);      dataGridColumn=null;     }     this.columns=titleArray;     titleArray=null;    }    this.dataProvider=xml.children();    initRightContext();   }      //加入DataGrid   public function addModel(value:ArrayMap):void{    for(var i:int=0;i<value.getLength();i++){     if(value.get(i) is BaseXmlModel)         addRowByModel(value.get(i) as BaseXmlModel);    }   }      //通过model加入新的一行   public function addRowByModel(value:BaseXmlModel):void{    var dataXml:XML=this.xml.appendChild(XML(value.getBaseXmlValue()));    this.dataProvider=dataXml.children();   }      //直接把数值插入新的一行   public function addRowByValue(...arg):void{    var num:int=arg.length;    var xmllist:XMLList=this.titleXml.children();    if(num==xmllist.length()){     var model:BaseXmlModel=new BaseXmlModel;     for(var i:int=0;i<num;i++){      model.put(XML(XML(xmllist[i]).child("ename")).toString(),arg[i]);     }     addRowByModel(model);     model=null;    }else{     Alert.show("行数据不正确","提示");    }   }      //删除其中一行   public function removeDataGridRow(num:int):void{    var xmlModel:XmlModel=new XmlModel(this.xml);    xmlModel.deleteXmlByIndex(num);    this.xml=XML(xmlModel.getOriginalXmlValue());   }      //清空数据单元   public function cleanDataGridRow():void{    this.xml=XML("<nodes />");   }      //获取表格高度   public function getDataGridRowLenght():int{    return this.xml.children().length();   }      //空白处右键   private function initRightContext():void   {    var contextMenu:ContextMenu=new ContextMenu();    contextMenu.hideBuiltInItems();        if (downloadPolicy == "on")    {     var saveExcelContextMenuItem:ContextMenuItem=new ContextMenuItem("导出为Excel");     saveExcelContextMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveExcel);     contextMenu.customItems.push(saveExcelContextMenuItem);    }        this.contextMenu=contextMenu;   }      //导出Excel   private function saveExcel(event:ContextMenuEvent):void   {    //loadDGInExcel(this, 'http://127.0.0.1:8080/SaleSystem/services/ExcelExport.jsp');    loadDGInExcelBySave(this);   }  ]]> </fx:Script> <fx:Script>  <![CDATA[   /**    * Simple script to convert a Datagrid to a HTML table and then    * pass it on to an external excel exporter    *    */      //Libs that are mostly used   //(only a number are necessary for the datagrid conversion and export)   import flash.errors.*;   import flash.events.*;   import flash.external.*;   import flash.net.URLRequest;   import flash.net.URLVariables;      /**    * Convert the datagrid to a html table    * Styling etc. can be done externally    *    * @param: dg Datagrid Contains the datagrid that needs to be converted    * @returns: String    */   private function convertDGToHTMLTable(dg:DataGrid):String   {    //Set default values    var font:String=dg.getStyle('fontFamily');    var size:String=dg.getStyle('fontSize');    var str:String='';    var colors:String='';    var style:String='style="font-family:' + font + ';font-size:' + size + 'pt;"';    var hcolor:Array;        //Retrieve the headercolor    if (dg.getStyle("headerColor") != undefined)    {     hcolor=[dg.getStyle("headerColor")];    }    else    {     hcolor=dg.getStyle("headerColors");    }        //Set the htmltabel based upon knowlegde from the datagrid    //flex3    //str+='<table width="' + dg.width + '" border="1"><thead><tr width="' + dg.width + '" style="background-color:#' + Number((hcolor[0])).toString(16) + '" mce_style="background-color:#' + Number((hcolor[0])).toString(16) + '">';    //flex4    str+='<table width="' + dg.width + '" border="1"><thead><tr width="' + dg.width + '" style="background-color:#' + 0xffffff.toString(16) + '" mce_style="background-color:#' + 0xffffff.toString(16) + '">';        //Set the tableheader data (retrieves information from the datagrid header    for (var i:int=0; i < dg.columns.length; i++)    {     colors=dg.getStyle("themeColor");          if (dg.columns[i].headerText != undefined)     {      str+="<th " + style + ">" + dg.columns[i].headerText + "</th>";     }     else     {      str+="<th " + style + ">" + dg.columns[i].dataField + "</th>";     }    }    str+="</tr></thead><tbody>";    colors=dg.getStyle("alternatingRowColors");        //Loop through the records in the dataprovider and    //insert the column information into the table    for (var j:int=0; j < dg.dataProvider.length; j++)    {     str+="<tr width=/"" + Math.ceil(dg.width) + "/">";          for (var k:int=0; k < dg.columns.length; k++)     {            //Do we still have a valid item?      if (dg.dataProvider.getItemAt(j) != undefined && dg.dataProvider.getItemAt(j) != null)      {              //Check to see if the user specified a labelfunction which we must       //use instead of the dataField       if (dg.columns[k].labelFunction != undefined)       {        str+="<td width=/"" + Math.ceil(dg.columns[k].width) + "/" " + style + ">" + dg.columns[k].labelFunction(dg.dataProvider.getItemAt(j), dg.columns[k].dataField) + "</td>";               }       else       {        //Our dataprovider contains the real data        //We need the column information (dataField)        //to specify which key to use.        str+="<td width=/"" + Math.ceil(dg.columns[k].width) + "/" " + style + ">" + dg.dataProvider.getItemAt(j)[dg.columns[k].dataField] + "</td>";       }      }     }     str+="</tr>";    }    str+="</tbody></table>";        return str;   }      /**    * Load a specific datagrid into Excel    * This method passes the htmltable string to an backend script which then    * offers the excel download to the user.    * The reason for not using a copy to clipboard and then javascript to    * insert it into Excel is that this mostly will fail because of the user    * setup (Webbrowser configuration).    *    * @params: dg Datagrid The Datagrid that will be loaded into Excel    * @params: url String The location of the excel export file    */   private function loadDGInExcel(dg:DataGrid, url:String):void   {        //Pass the htmltable in a variable so that it can be delivered    //to the backend script    var variables:URLVariables=new URLVariables();    variables.htmltable=convertDGToHTMLTable(dg);        //Setup a new request and make sure that we are    //sending the data through a post    var u:URLRequest=new URLRequest(url);    u.data=variables; //Pass the variables    u.method=URLRequestMethod.POST; //Don't forget that we need to send as POST        //Navigate to the script    //We can use _self here, since the script will through a filedownload header    //which results in offering a download to the user (and still remaining in you Flex app.)    navigateToURL(u, "_self");   }      private function loadDGInExcelBySave(dg:DataGrid):void   {    var ba:ByteArray=new ByteArray;    ba.writeUTF(convertDGToHTMLTable(dg));    var _fileRef:FileReference=new FileReference();    _fileRef.save(ba, "data.xls"); //保存到磁盘,会出现个系统保存对话框。    ba.clear();   }  ]]--> </fx:Script></mx:DataGrid>

代码的

<fx:XML id="titleXml" xmlns="">   <nodes>    <node width="20">     <ename>key1</ename>     <cname>key1</cname>    </node>    <node width="30%">     <ename>key2</ename>     <cname>key2</cname>    </node>   </nodes>  </fx:XML>

定义的是title

代码的

<fx:XML id="xml" xmlns="">   <nodes>    <node>     <key1>value1</key1>     <key2>value2</key2>    </node>   </nodes>  </fx:XML>

定义的是内容

调用的application

<?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"       xmlns:local="*"       creationComplete="{complete()}" xmlns:view="com.shine.framework.core.view.*"> <fx:Declarations>  <fx:XML id="titleXml" xmlns="">   <nodes>    <node>     <ename>key1</ename>     <cname>key1</cname>    </node>    <node>     <ename>key2</ename>     <cname>key2</cname>    </node>   </nodes>  </fx:XML>  <fx:XML id="dataXml" xmlns="">   <nodes>    <node>     <key1>value1</key1>     <key2>value2</key2>    </node>    <node>     <key1>value3</key1>     <key2>value4</key2>    </node>   </nodes>  </fx:XML> </fx:Declarations> <fx:Script>  <!--[CDATA[   private function complete():void{    sunshineDataGrid.dataProvider=dataXml.node;   }  ]]--> </fx:Script> <view:SunshineDataGrid id="sunshineDataGrid" width="100%" height="100%" titleXml="{titleXml}" downloadPolicy="on" /></s:Application>

实际效果

    当然也可以动态定义宽度,也可以动态控制显示图片还是html都可以,下一篇文章给大家介绍一下

    http://blog.csdn.net/arjick/article/details/6450992

           

猜你喜欢

转载自blog.csdn.net/qq_44952688/article/details/89469707