<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>八点钟的太阳</title>
    <description>Penitence is something that enervates our spirit, causing a greater loss than the loss itself and making a bigger mistake than the mistake itself. So never regret.</description>
    <link>http://dmewy.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>java如何操作Excel</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227117" style="color:red;">http://dmewy.javaeye.com/blog/227117</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">一.读取Excel文件内容

    java 代码

       1. /**读取Excel文件的内容  
       2.  * @param file  待读取的文件  
       3.  * @return  
       4.  */  
       5. public static String readExcel(File file){   
       6.     StringBuffer sb = new StringBuffer();   
       7.        
       8.     Workbook wb = null;   
       9.     try {   
      10.         //构造Workbook（工作薄）对象   
      11.         wb=Workbook.getWorkbook(file);   
      12.     } catch (BiffException e) {   
      13.         e.printStackTrace();   
      14.     } catch (IOException e) {   
      15.         e.printStackTrace();   
      16.     }   
      17.        
      18.     if(wb==null)   
      19.         return null;   
      20.        
      21.     //获得了Workbook对象之后，就可以通过它得到Sheet（工作表）对象了   
      22.     Sheet[] sheet = wb.getSheets();   
      23.        
      24.     if(sheet!=null&amp;&amp;sheet.length&gt;0){   
      25.         //对每个工作表进行循环   
      26.         for(int i=0;i
      27.             //得到当前工作表的行数   
      28.             int rowNum = sheet[i].getRows();   
      29.             for(int j=0;j
      30.                 //得到当前行的所有单元格   
      31.                 Cell[] cells = sheet[i].getRow(j);   
      32.                 if(cells!=null&amp;&amp;cells.length&gt;0){   
      33.                     //对每个单元格进行循环   
      34.                     for(int k=0;k
      35.                         //读取当前单元格的值   
      36.                         String cellValue = cells[k].getContents();   
      37.                         sb.append(cellValue+&quot;\t&quot;);   
      38.                     }   
      39.                 }   
      40.                 sb.append(&quot;\r\n&quot;);   
      41.             }   
      42.             sb.append(&quot;\r\n&quot;);   
      43.         }   
      44.     }   
      45.     //最后关闭资源，释放内存   
      46.     wb.close();   
      47.     return sb.toString();   
      48. }   

二.写入Excel文件

    这里有很多格式了，比如文本内容加粗，加上某些颜色等，可以参考jxl的api，同时还推荐一篇不错的文章：http://www.ibm.com/developerworks/cn/java/l-javaExcel/?ca=j-t10
    java 代码

       1. /**生成一个Excel文件  
       2.      * @param fileName  要生成的Excel文件名  
       3.      */  
       4.     public static void writeExcel(String fileName){   
       5.         WritableWorkbook wwb = null;   
       6.         try {   
       7.             //首先要使用Workbook类的工厂方法创建一个可写入的工作薄(Workbook)对象   
       8.             wwb = Workbook.createWorkbook(new File(fileName));   
       9.         } catch (IOException e) {   
      10.             e.printStackTrace();   
      11.         }   
      12.         if(wwb!=null){   
      13.             //创建一个可写入的工作表   
      14.             //Workbook的createSheet方法有两个参数，第一个是工作表的名称，第二个是工作表在工作薄中的位置   
      15.             WritableSheet ws = wwb.createSheet(&quot;sheet1&quot;, 0);   
      16.                
      17.             //下面开始添加单元格   
      18.             for(int i=0;i&lt;10;i++){   
      19.                 for(int j=0;j&lt;5;j++){   
      20.                     //这里需要注意的是，在Excel中，第一个参数表示列，第二个表示行   
      21.                     Label labelC = new Label(j, i, &quot;这是第&quot;+(i+1)+&quot;行，第&quot;+(j+1)+&quot;列&quot;);   
      22.                     try {   
      23.                         //将生成的单元格添加到工作表中   
      24.                         ws.addCell(labelC);   
      25.                     } catch (RowsExceededException e) {   
      26.                         e.printStackTrace();   
      27.                     } catch (WriteException e) {   
      28.                         e.printStackTrace();   
      29.                     }   
      30.   
      31.                 }   
      32.             }   
      33.   
      34.             try {   
      35.                 //从内存中写入文件中   
      36.                 wwb.write();   
      37.                 //关闭资源，释放内存   
      38.                 wwb.close();   
      39.             } catch (IOException e) {   
      40.                 e.printStackTrace();   
      41.             } catch (WriteException e) {   
      42.                 e.printStackTrace();   
      43.             }   
      44.         }   
      45.     }    

三.在一个Excel文件中查找是否包含某一个关键字

    java 代码

       1. /**搜索某一个文件中是否包含某个关键字  
       2.      * @param file  待搜索的文件  
       3.      * @param keyWord  要搜索的关键字  
       4.      * @return  
       5.      */  
       6.     public static boolean searchKeyWord(File file,String keyWord){   
       7.         boolean res = false;   
       8.            
       9.         Workbook wb = null;   
      10.         try {   
      11.             //构造Workbook（工作薄）对象   
      12.             wb=Workbook.getWorkbook(file);   
      13.         } catch (BiffException e) {   
      14.             return res;   
      15.         } catch (IOException e) {   
      16.             return res;   
      17.         }   
      18.            
      19.         if(wb==null)   
      20.             return res;   
      21.            
      22.         //获得了Workbook对象之后，就可以通过它得到Sheet（工作表）对象了   
      23.         Sheet[] sheet = wb.getSheets();   
      24.            
      25.         boolean breakSheet = false;   
      26.            
      27.         if(sheet!=null&amp;&amp;sheet.length&gt;0){   
      28.             //对每个工作表进行循环   
      29.             for(int i=0;i
      30.                 if(breakSheet)   
      31.                     break;   
      32.                    
      33.                 //得到当前工作表的行数   
      34.                 int rowNum = sheet[i].getRows();   
      35.                    
      36.                 boolean breakRow = false;   
      37.                    
      38.                 for(int j=0;j
      39.                     if(breakRow)   
      40.                         break;   
      41.                     //得到当前行的所有单元格   
      42.                     Cell[] cells = sheet[i].getRow(j);   
      43.                     if(cells!=null&amp;&amp;cells.length&gt;0){   
      44.                         boolean breakCell = false;   
      45.                         //对每个单元格进行循环   
      46.                         for(int k=0;k
      47.                             if(breakCell)   
      48.                                 break;   
      49.                             //读取当前单元格的值   
      50.                             String cellValue = cells[k].getContents();   
      51.                             if(cellValue==null)   
      52.                                 continue;   
      53.                             if(cellValue.contains(keyWord)){   
      54.                                 res = true;   
      55.                                 breakCell = true;   
      56.                                 breakRow = true;   
      57.                                 breakSheet = true;   
      58.                             }   
      59.                         }   
      60.                     }   
      61.                 }   
      62.             }   
      63.         }   
      64.         //最后关闭资源，释放内存   
      65.         wb.close();   
      66.            
      67.         return res;   
      68.     }   

四.往Excel中插入图片图标

    插入图片的实现很容易，参看以下代码：
    java 代码

       1. /**往Excel中插入图片  
       2.  * @param dataSheet  待插入的工作表  
       3.  * @param col 图片从该列开始  
       4.  * @param row 图片从该行开始  
       5.  * @param width 图片所占的列数  
       6.  * @param height 图片所占的行数  
       7.  * @param imgFile 要插入的图片文件  
       8.  */  
       9. public static void insertImg(WritableSheet dataSheet, int col, int row, int width,   
      10.         int height, File imgFile){   
      11.     WritableImage img = new WritableImage(col, row, width, height, imgFile);   
      12.     dataSheet.addImage(img);   
      13. }    

    以上代码的注释已经很清楚了，大概也就不用再解释了，我们可以用如下程序验证：
    java 代码

       1.     try {   
       2.         //创建一个工作薄   
       3. WritableWorkbook workbook = Workbook.createWorkbook(new File(&quot;D:/test1.xls&quot;));   
       4. //待插入的工作表   
       5. WritableSheet imgSheet = workbook.createSheet(&quot;Images&quot;,0);   
       6. //要插入的图片文件   
       7. File imgFile = new File(&quot;D:/1.png&quot;);   
       8. //图片插入到第二行第一个单元格，长宽各占六个单元格   
       9. insertImg(imgSheet,0,1,6,6,imgFile);   
      10. workbook.write();   
      11. workbook.close();   
      12.  catch (IOException e) {   
      13. e.printStackTrace();   
      14.  catch (WriteException e) {   
      15. e.printStackTrace();    

     但是jxl只支持png格式的图片，jpg格式和gif格式都不支持</pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227117#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 17:36:18 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227117</link>
        <guid>http://dmewy.javaeye.com/blog/227117</guid>
      </item>
      <item>
        <title>Prototype 1.4.0 源码解读----全文注释版(下)</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227100" style="color:red;">http://dmewy.javaeye.com/blog/227100</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="js">/*【Observer模式框架】 观察对象仅仅针对表单和表单域*/

/*========================================================================================*/

Abstract.TimedObserver = function() {}//定义了基于定时器的观察模式基类后面的类都继承了这个类



Abstract.TimedObserver.prototype = {

    this.frequency = frequency;//观察频率



    this.element = $(element);//被观察的对象



    this.callback = callback;//回调函数接受参数 被观察对象自身和触发事件时的值



    this.lastValue = this.getValue();//这是观察的值！！



    this.registerCallback();

  },

//注册回调函数



    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);

  },

//每一个时间片触发一次该事件



    var value = this.getValue();

    if (this.lastValue != value) {

      this.callback(this.element, value);

      this.lastValue = value;

    }

  }

}

//【Form.Element.Observer类】实现了getvalue方法



Form.Element.Observer = Class.create();

Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {

    return Form.Element.getValue(this.element);

  }

});

//【Form.Observer类】实现了getvalue方法，只要有一个表单域发生变化就会触发回调



Form.Observer = Class.create();

Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {

    return Form.serialize(this.element);

  }

});

//【Abstract.EventObserver 类】基于事件的Oberver模式的基类 后面的具体类都继承这个类



Abstract.EventObserver = function() {}

Abstract.EventObserver.prototype = {

    this.element = $(element);

    this.callback = callback;

    this.lastValue = this.getValue();

    if (this.element.tagName.toLowerCase() == 'form')

      this.registerFormCallbacks();

    else

      this.registerCallback(this.element);

  },

//每次发生事件时被调用 内部调用 无需显示调用



    var value = this.getValue();

    if (this.lastValue != value) {

      this.callback(this.element, value);

      this.lastValue = value;

    }

  },

//注册表表单域事件



    var elements = Form.getElements(this.element);

    for (var i = 0; i &lt; elements.length; i++)

      this.registerCallback(elements[i]);

  },

    if (element.type) {

      switch (element.type.toLowerCase()) {

                      Event.observe(element, 'click', this.onElementEvent.bind(this));

          break;

                                        Event.observe(element, 'change', this.onElementEvent.bind(this));

          break;

      }

    }

  }

}

//【Form.Element.EventObserver】



Form.Element.EventObserver = Class.create();

Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {

    return Form.Element.getValue(this.element);

  }

});

//【Form.EventObserver】



Form.EventObserver = Class.create();

Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {

    return Form.serialize(this.element);

  }

});

/*========================================================================================*/

/*【事件处理:对Event对象的扩展】对javascript事件处理机制进行封装*/

/*========================================================================================*/

if (!window.Event) {

  var Event = new Object();

}

Object.extend(Event, {

       9,

   13,

      27,

     37,

       38,

    39,

     40,

   46,

//获取触发事件的对象



    return event.target || event.srcElement;

  },

    return (((event.which) &amp;&amp; (event.which == 1)) ||

            ((event.button) &amp;&amp; (event.button == 1)));

  },

    return event.pageX || (event.clientX +

      (document.documentElement.scrollLeft || document.body.scrollLeft));

  },

    return event.pageY || (event.clientY +

      (document.documentElement.scrollTop || document.body.scrollTop));

  },

//停止事件的传递



    if (event.preventDefault) {

      event.preventDefault();

      event.stopPropagation();

    } else {

      event.returnValue = false;

      event.cancelBubble = true;

    }

  },

  // find the first node with the given tagName, starting from the



  // node the event was triggered on; traverses the DOM upwards



    var element = Event.element(event);

    while (element.parentNode &amp;&amp; (!element.tagName ||

        (element.tagName.toUpperCase() != tagName.toUpperCase())))

      element = element.parentNode;

    return element;

  },

    if (!this.observers) this.observers = [];

    if (element.addEventListener) {

      this.observers.push([element, name, observer, useCapture]);

      element.addEventListener(name, observer, useCapture);

    } else if (element.attachEvent) {

      this.observers.push([element, name, observer, useCapture]);

      element.attachEvent('on' + name, observer);

    }

  },

//删除所有通过Event.observers绑定的事件



    if (!Event.observers) return;

    for (var i = 0; i &lt; Event.observers.length; i++) {

      Event.stopObserving.apply(this, Event.observers[i]);

      Event.observers[i][0] = null;

    }

    Event.observers = false;

  },

//绑定一个事件



    var element = $(element);

    useCapture = useCapture || false;

    if (name == 'keypress' &amp;&amp;

        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)

        || element.attachEvent))

      ;

    this._observeAndCache(element, name, observer, useCapture);

  },

//取消事件绑定



    var element = $(element);

    useCapture = useCapture || false;

    if (name == 'keypress' &amp;&amp;

        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)

        || element.detachEvent))

      ;

    if (element.removeEventListener) {

      element.removeEventListener(name, observer, useCapture);

    } else if (element.detachEvent) {

      element.detachEvent('on' + name, observer);

    }

  }

});


var Position = {

  // NOT neeeded for page scrolling, only if draggable contained in



  // scrollable elements



  // must be called before calling withinIncludingScrolloffset, every time the



  // page is scrolled用于计算滚动条的位置信息



    this.deltaX = window.pageXOffset

                || document.documentElement.scrollLeft

                || document.body.scrollLeft

                || 0;

    this.deltaY = window.pageYOffset

                || document.documentElement.scrollTop

                || document.body.scrollTop

                || 0;

  },

//计算节点的绝对滚动位置返回包含两个元素的数组到文档左侧 顶部的距离



    var valueT = 0, valueL = 0;

    do {

      valueT += element.scrollTop || 0;

      valueL += element.scrollLeft || 0;

      element = element.parentNode;

    } while (element);

    return [valueL, valueT];

  },

//计算结点相对于文档的绝对滚动位置，返回包含两个元素的数组到文档左侧 顶部的距离



    var valueT = 0, valueL = 0;

    do {

      valueT += element.offsetTop || 0;

      valueL += element.offsetLeft || 0;

      element = element.offsetParent;

    } while (element);

    return [valueL, valueT];

  },

//相对位置



    var valueT = 0, valueL = 0;

    do {

      valueT += element.offsetTop || 0;

      valueL += element.offsetLeft || 0;

      element = element.offsetParent;

      if (element) {

        p = Element.getStyle(element, 'position');

        if (p == 'relative' || p == 'absolute') break;

      }

    } while (element);

    return [valueL, valueT];

  },

    if (element.offsetParent) return element.offsetParent;

    if (element == document.body) return element;

    while ((element = element.parentNode) &amp;&amp; element != document.body)

      if (Element.getStyle(element, 'position') != 'static')

        return element;

    return document.body;

  },

  // caches x/y coordinate pair to use with overlap是否在element内



    if (this.includeScrollOffsets)

      return this.withinIncludingScrolloffsets(element, x, y);

    this.xcomp = x;

    this.ycomp = y;

    this.offset = this.cumulativeOffset(element);

    return (y &gt;= this.offset[1] &amp;&amp;

            y &lt; this.offset[1] + element.offsetHeight &amp;&amp;

            x &gt;= this.offset[0] &amp;&amp;

            x &lt; this.offset[0] + element.offsetWidth);

  },

    var offsetcache = this.realOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;

    this.ycomp = y + offsetcache[1] - this.deltaY;

    this.offset = this.cumulativeOffset(element);

    return (this.ycomp &gt;= this.offset[1] &amp;&amp;

            this.ycomp &lt; this.offset[1] + element.offsetHeight &amp;&amp;

            this.xcomp &gt;= this.offset[0] &amp;&amp;

            this.xcomp &lt; this.offset[0] + element.offsetWidth);

  },

  // within must be called directly before



    if (!mode) return 0;

    if (mode == 'vertical')

      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /

        element.offsetHeight;

    if (mode == 'horizontal')

      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /

        element.offsetWidth;

  },

//克隆结点 常用于拖放



    source = $(source);

    target = $(target);

    target.style.position = 'absolute';

    var offsets = this.cumulativeOffset(source);

    target.style.top = offsets[1] + 'px';

    target.style.left = offsets[0] + 'px';

    target.style.width = source.offsetWidth + 'px';

    target.style.height = source.offsetHeight + 'px';

  },

    var valueT = 0, valueL = 0;

    var element = forElement;

    do {

      valueT += element.offsetTop || 0;

      valueL += element.offsetLeft || 0;

      // Safari fix



      if (element.offsetParent==document.body)

        if (Element.getStyle(element,'position')=='absolute') break;

    } while (element = element.offsetParent);

    element = forElement;

    do {

      valueT -= element.scrollTop || 0;

      valueL -= element.scrollLeft || 0;

    } while (element = element.parentNode);

    return [valueL, valueT];

  },

    var options = Object.extend({

        true,

         true,

       true,

      true,

      0,

        }, arguments[2] || {})

    // find page position of source



    source = $(source);

    var p = Position.page(source);

    // find coordinate system to use



    target = $(target);

    var delta = [0, 0];

    var parent = null;

    // delta [0,0] will do fine with ;fixed elements,



    // ;needs offsetParent deltas



    if (Element.getStyle(target,'position') == 'absolute') {

      parent = Position.offsetParent(target);

      delta = Position.page(parent);

    }

    // correct by body offsets (fixes Safari)



    if (parent == document.body) {

      delta[0] -= document.body.offsetLeft;

      delta[1] -= document.body.offsetTop;

    }

    // set position



    if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) +

'px';

    if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';

    if(options.setWidth) target.style.width = source.offsetWidth + 'px';

    if(options.setHeight) target.style.height = source.offsetHeight + 'px';

  },

//绝对定位



    element = $(element);

    if (element.style.position == 'absolute') return;

    Position.prepare();

    var offsets = Position.positionedOffset(element);

    var top = offsets[1];

    var left = offsets[0];

    var width = element.clientWidth;

    var height = element.clientHeight;

    element._originalLeft = left - parseFloat(element.style.left || 0);

    element._originalTop = top - parseFloat(element.style.top || 0);

    element._originalWidth = element.style.width;

    element._originalHeight = element.style.height;

    element.style.position = 'absolute';

    element.style.top = top + 'px';

    element.style.left = left + 'px';;

    element.style.width = width + 'px';;

    element.style.height = height + 'px';;

  },

//相对定位



    element = $(element);

    if (element.style.position == 'relative') return;

    Position.prepare();

    element.style.position = 'relative';

    var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);

    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top = top + 'px';

    element.style.left = left + 'px';

    element.style.height = element._originalHeight;

    element.style.width = element._originalWidth;

  }

}

// Safari returns margins on body which is incorrect if the child is absolutely



// positioned. For performance reasons, redefine Position.cumulativeOffset for



// KHTML/WebKit only.



if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {

  Position.cumulativeOffset = function(element) {

    var valueT = 0, valueL = 0;

    do {

      valueT += element.offsetTop || 0;

      valueL += element.offsetLeft || 0;

      if (element.offsetParent == document.body)

        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;

    } while (element);

    return [valueL, valueT];

  }

}</pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227100#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 17:09:24 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227100</link>
        <guid>http://dmewy.javaeye.com/blog/227100</guid>
      </item>
      <item>
        <title>Prototype 1.4.0 源码解读----全文注释版(中)</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227099" style="color:red;">http://dmewy.javaeye.com/blog/227099</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="js">* 【Ajax模块】

/*========================================================================================*/

//【ajax对象】


var Ajax = {//创建浏览器兼容的XMLHttpRequest对象


    return Try.these(

      function() {return new ActiveXObject('Msxml2.XMLHTTP')},

      function() {return new ActiveXObject('Microsoft.XMLHTTP')},

      function() {return new XMLHttpRequest()}

    ) || false;

  },

//当前激活的请求数目


  activeRequestCount: 0

}

//【Ajax.Responders对象】


Ajax.Responders = {

    this.responders._each(iterator);

  },

//注册一个响应代理


    if (!this.include(responderToAdd))

      this.responders.push(responderToAdd);

  },

//删除一个响应代理


    this.responders = this.responders.without(responderToRemove);

  },

//分发一个回调函数，让所有半酣callback回调函数事件标识符的响应代理都被调用


//传递三个参数最后一个可选表示Json对象


    this.each(function(responder) {

      if (responder[callback] &amp;&amp; typeof responder[callback] == 'function') {

        try {

          responder[callback].apply(responder, [request, transport, json]);

        } catch (e) {}

      }

    });

  }

};

Object.extend(Ajax.Responders, Enumerable);

//统计当前活动请求的数目


Ajax.Responders.register({

//开始创建了一个请求


    Ajax.activeRequestCount++;

  },

//请求结束


    Ajax.activeRequestCount--;

  }

});

//【Ajax.Base类】进行服务器通信的基类


Ajax.Base = function() {};

Ajax.Base.prototype = {

    this.options = {

           'post',

           ''

    }

    Object.extend(this.options, options || {});

  },

    return this.transport.status == undefined

        || this.transport.status == 0

        || (this.transport.status &gt;= 200 &amp;&amp; this.transport.status &lt; 300);

  },

    return !this.responseIsSuccess();

  }

}

//【Ajax.Request类】用于向服务器端发送请求，封装了XmlHttpRequest


Ajax.Request = Class.create();

Ajax.Request.Events =

  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {

    this.transport = Ajax.getTransport();

    this.setOptions(options);//使用基类方法设置


    this.request(url);

  },

//向指定url发送请求 一般不会显示调用


    var parameters = this.options.parameters || '';

    if (parameters.length &gt; 0) parameters += '&amp;_=';

    try {

      this.url = url;

      if (this.options.method == 'get' &amp;&amp; parameters.length &gt; 0)

        this.url += (this.url.match(/\?/) ? '&amp;' : '?') + parameters;

      Ajax.Responders.dispatch('onCreate', this, this.transport);

      this.transport.open(this.options.method, this.url,

        this.options.asynchronous);

      if (this.options.asynchronous) {

        this.transport.onreadystatechange = this.onStateChange.bind(this);

        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);

      }

      this.setRequestHeaders();

      var body =

      this.transport.send(this.options.method ==

    } catch (e) {

      this.dispatchException(e);

    }

  },

//设置请求的Http头 类内部使用 一般无需显示调用


    var requestHeaders =

      ['X-Requested-With', 'XMLHttpRequest',

       'X-Prototype-Version', Prototype.Version];

    if (this.options.method == 'post') {

      requestHeaders.push('Content-type',

        'application/x-www-form-urlencoded');

      /* Force &quot;Connection: close&quot; for Mozilla browsers to work around

       * a bug where XMLHttpReqeuest sends an incorrect Content-length

       * header. See Mozilla Bugzilla #246651.

       */

      if (this.transport.overrideMimeType)

        requestHeaders.push('Connection', 'close');

    }

    if (this.options.requestHeaders)

      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);

    for (var i = 0; i &lt; requestHeaders.length; i += 2)

      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);

  },

//检测XMLHttpRquest对象的onstatechange事件类内部使用 一般无需显示调用


    var readyState = this.transport.readyState;

    if (readyState != 1)

      this.respondToReadyState(this.transport.readyState);

  },

//获取指定的Http头的内容


    try {

      return this.transport.getResponseHeader(name);

    } catch (e) {}

  },

//如果服务器返回了Http头&quot;X-JOSN&quot;则将其作为js执行并返回执行结果


    try {

      return eval(this.header('X-JSON'));

    } catch (e) {}

  },

//将XMLHttpRequest返回的responseText作为JS语句执行并返回执行结果


    try {

      return eval(this.transport.responseText);

    } catch (e) {

      this.dispatchException(e);

    }

  },

//处理XMLHttpRequest的readystate属性根据成功或失败调用Options对象中相应的回调函数


//同时通知Ajax.Responders中注册的响应处理句柄


    var event = Ajax.Request.Events[readyState];

    var transport = this.transport, json = this.evalJSON();

    if (event == 'Complete') {

      try {

        (this.options['on' + this.transport.status]

                || Prototype.emptyFunction)(transport, json);

      } catch (e) {

        this.dispatchException(e);

      }

      if ((this.header('Content-type') || '').match(/^text\/javascript/i))

        this.evalResponse();

    }

    try {

      (this.options['on' + event] || Prototype.emptyFunction)(transport, json);

      Ajax.Responders.dispatch('on' + event, this, transport, json);

    } catch (e) {

      this.dispatchException(e);

    }

      if (event == 'Complete')

      this.transport.onreadystatechange = Prototype.emptyFunction;

  },

    (this.options.onException || Prototype.emptyFunction)(this, exception);

    Ajax.Responders.dispatch('onException', this, exception);

  }

});

/*========================================================================================*/

 


//【Ajax.Updater类】用于将获取的内容填充到指定的容器中去


Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {

//重写了构造函数


    this.containers = {

                  }

    this.transport = Ajax.getTransport();

    this.setOptions(options);//可以指定evalscripts属性和insertion属性


    var onComplete = this.options.onComplete || Prototype.emptyFunction;

    this.options.onComplete = (function(transport, object) {

      this.updateContent();

      onComplete(transport, object);

    }).bind(this);

    this.request(url);

  },

    var receiver = this.responseIsSuccess() ?

     

    var response = this.transport.responseText;

    if (!this.options.evalScripts)

      response = response.stripScripts();

    if (receiver) {

      if (this.options.insertion) {

        new this.options.insertion(receiver, response);

      } else {

        Element.update(receiver, response);

      }

    }

    if (this.responseIsSuccess()) {

      if (this.onComplete)

        setTimeout(this.onComplete.bind(this), 10);

    }

  }

});

/*========================================================================================*/

//【Ajax.PeriodicalUpdater类】用于定时执行服务器异步调用，功能与Updater相同只是有了定时功能


Ajax.PeriodicalUpdater = Class.create();

Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {

    this.setOptions(options);

    this.onComplete = this.options.onComplete;

//区别就在下面两个属性 频率 衰减参数 指数增长！只要有一次不同旧回复原有频率


    this.frequency = (this.options.frequency || 2);

    this.decay = (this.options.decay || 1);

    this.updater = {};

    this.container = container;

    this.url = url;

    this.start();

  },

    this.options.onComplete = this.updateComplete.bind(this);

    this.onTimerEvent();

  },

    this.updater.onComplete = undefined;

    clearTimeout(this.timer);

    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);

  },

    if (this.options.decay) {

      this.decay = (request.responseText == this.lastText ?

       

      this.lastText = request.responseText;

    }

    this.timer = setTimeout(this.onTimerEvent.bind(this),

      this.decay * this.frequency * 1000);

  },

    this.updater = new Ajax.Updater(this.container, this.url, this.options);

  }

});

/*========================================================================================*/

/*【文档操作的封装】

/*========================================================================================*/

//返回了一个数组包含了所有符合条件的结点的引用


document.getElementsByClassName = function(className, parentElement) { //parentElement不指定


就在全局查找

  var children = ($(parentElement) || document.body).getElementsByTagName('*');

  return $A(children).inject([], function(elements, child) {

    if (child.className.match(new RegExp(&quot;(^|\\s)&quot; + className + &quot;(\\s|$)&quot;)))

      elements.push(child);

    return elements;

  });

}

/*【Element对象】用于对文档结点做一些统一的操作

*/

if (!window.Element) {

  var Element = new Object();

}

Object.extend(Element, {

    return $(element).style.display != 'none';

  },

//指定结点可见性的切换


    for (var i = 0; i &lt; arguments.length; i++) {

      var element = $(arguments[i]);

     

    }

  },

    for (var i = 0; i &lt; arguments.length; i++) {

      var element = $(arguments[i]);

      element.style.display = 'none';

    }

  },

    for (var i = 0; i &lt; arguments.length; i++) {

      var element = $(arguments[i]);

      element.style.display = '';

    }

  },

    element = $(element);

    element.parentNode.removeChild(element);

  },

//将html片段填充到element指定的结点中


    $(element).innerHTML = html.stripScripts();

    setTimeout(function() {html.evalScripts()}, 10);

  },

//获得element的绝对高度


    element = $(element);

    return element.offsetHeight;

  },

    return new Element.ClassNames(element);

  },

    if (!(element = $(element))) return;

    return Element.classNames(element).include(className);

  },

    if (!(element = $(element))) return;

    return Element.classNames(element).add(className);

  },

    if (!(element = $(element))) return;

    return Element.classNames(element).remove(className);

  },

  // removes whitespace-only text node children


    element = $(element);

    for (var i = 0; i &lt; element.childNodes.length; i++) {

      var node = element.childNodes[i];

      if (node.nodeType == 3 &amp;&amp; !/\S/.test(node.nodeValue))

        Element.remove(node);

    }

  },

    return $(element).innerHTML.match(/^\s*$/);

  },

//将浏览器的滚动条滚动到指定的结点的位置


    element = $(element);

    var x = y =

    window.scrollTo(x, y);

  },

//得到element的结点的绝对样式


    element = $(element);

    var value = element.style[style.camelize()];

    if (!value) {

      if (document.defaultView &amp;&amp; document.defaultView.getComputedStyle) {

        var css = document.defaultView.getComputedStyle(element, null);

        value =

      } else if (element.currentStyle) {

        value = element.currentStyle[style.camelize()];

      }

    }

    if (window.opera &amp;&amp; ['left', 'top', 'right', 'bottom'].include(style))

      if (Element.getStyle(element, 'position') == 'static') value = 'auto';

    return value ==

  },

//设置结点样式 var style={background-color:'black',color:'red'} Element.setStyle


($('div1'),style)

    element = $(element);

    for (name in style)

      element.style[name.camelize()] = style[name];

  },

  

  //获得结点的宽度高度 该方法无论结点是否可见 都能获得其大小


    element = $(element);

    if (Element.getStyle(element, 'display') != 'none')

     

    // All *Width and *Height properties give 0 on elements with display none,


    // so enable the element temporarily


    var els = element.style;

    var originalVisibility = els.visibility;

    var originalPosition = els.position;

    els.visibility = 'hidden';

    els.position = 'absolute';

    els.display = '';

    var originalWidth = element.clientWidth;

    var originalHeight = element.clientHeight;

    els.display = 'none';

    els.position = originalPosition;

    els.visibility = originalVisibility;

   

  },

//相对定位


    element = $(element);

    var pos = Element.getStyle(element, 'position');

    if (pos == 'static' || !pos) {

      element._madePositioned = true;

      element.style.position = 'relative';

      // Opera returns the offset relative to the positioning context, when an


      // element is position relative but top and left have not been defined


      if (window.opera) {

        element.style.top = 0;

        element.style.left = 0;

      }

    }

  },

//取消相对定位


    element = $(element);

    if (element._madePositioned) {

      element._madePositioned = undefined;

      element.style.position =

        element.style.top =

        element.style.left =

        element.style.bottom =

        element.style.right = '';

    }

  },

//使结点隐藏超出的部分 overflow=relative


    element = $(element);

    if (element._overflow) return;

    element._overflow = element.style.overflow;

    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')

      element.style.overflow = 'hidden';

  },

    element = $(element);

    if (element._overflow) return;

    element.style.overflow = element._overflow;

    element._overflow = undefined;

  }

});

/*========================================================================================*/

//Toggle对象是Element.toggle方法的一个快捷用法


var Toggle = new Object();

Toggle.display = Element.toggle;

/*========================================================================================*/

//【Insertion命名空间】包含了4个类把指定的html片段插入到指定的结点的相应位置上


Abstract.Insertion = function(adjacency) {

  this.adjacency = adjacency;

}

Abstract.Insertion.prototype = {

    this.element = $(element);

    this.content = content.stripScripts();

    if (this.adjacency &amp;&amp; this.element.insertAdjacentHTML) {

      try {

        this.element.insertAdjacentHTML(this.adjacency, this.content);

      } catch (e) {

        if (this.element.tagName.toLowerCase() == 'tbody') {

          this.insertContent(this.contentFromAnonymousTable());

        } else {

          throw e;

        }

      }

    } else {

      this.range = this.element.ownerDocument.createRange();

      if (this.initializeRange) this.initializeRange();

      this.insertContent([this.range.createContextualFragment(this.content)]);

    }

    setTimeout(function() {content.evalScripts()}, 10);

  },

    var div = document.createElement('div');

    div.innerHTML = '&lt;table&gt;&lt;tbody&gt;' + this.content + '&lt;/tbody&gt;&lt;/table&gt;';

    return $A(div.childNodes[0].childNodes[0].childNodes);

  }

}

var Insertion = new Object();

Insertion.Before = Class.create();

Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {

    this.range.setStartBefore(this.element);

  },

    fragments.each((function(fragment) {

      this.element.parentNode.insertBefore(fragment, this.element);

    }).bind(this));

  }

});

Insertion.Top = Class.create();

Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {

    this.range.selectNodeContents(this.element);

    this.range.collapse(true);

  },

    fragments.reverse(false).each((function(fragment) {

      this.element.insertBefore(fragment, this.element.firstChild);

    }).bind(this));

  }

});

Insertion.Bottom = Class.create();

Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {

    this.range.selectNodeContents(this.element);

    this.range.collapse(this.element);

  },

    fragments.each((function(fragment) {

      this.element.appendChild(fragment);

    }).bind(this));

  }

});

Insertion.After = Class.create();

Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {

    this.range.setStartAfter(this.element);

  },

    fragments.each((function(fragment) {

      this.element.parentNode.insertBefore(fragment,

        this.element.nextSibling);

    }).bind(this));

  }

});

/*========================================================================================*/

//【Element.ClassNames】获得一个结点的所有的class名称组成的对象，实现了枚举接口


Element.ClassNames = Class.create();

Element.ClassNames.prototype = {

    this.element = $(element);

  },

    this.element.className.split(/\s+/).select(function(name) {

      return name.length &gt; 0;

    })._each(iterator);

  },

    this.element.className = className;

  },

    if (this.include(classNameToAdd)) return;

    this.set(this.toArray().concat(classNameToAdd).join(' '));

  },

    if (!this.include(classNameToRemove)) return;

    this.set(this.select(function(className) {

      return className != classNameToRemove;

    }).join(' '));

  },

    return this.toArray().join(' ');

  }

}

//表单域对象工具类


Object.extend(Element.ClassNames.prototype, Enumerable);

var Field = {

    for (var i = 0; i &lt; arguments.length; i++)

      $(arguments[i]).value = '';

  },

    $(element).focus();

  },

    for (var i = 0; i &lt; arguments.length; i++)

      if ($(arguments[i]).value == '') return false;

    return true;

  },

//选中表单域


    $(element).select();

  },

//focus + select


    element = $(element);

    element.focus();

    if (element.select)

      element.select();

  }

}

/*【Form】表单工具对象*/

var Form = {

//表单数据序列化


    var elements = Form.getElements($(form));

    var queryComponents = new Array();

    for (var i = 0; i &lt; elements.length; i++) {

      var queryComponent = Form.Element.serialize(elements[i]);

      if (queryComponent)

        queryComponents.push(queryComponent);

    }

    return queryComponents.join('&amp;');

  },

//获取所有表单域按照标记名排列


    form = $(form);

    var elements = new Array();

    for (tagName in Form.Element.Serializers) {

      var tagElements = form.getElementsByTagName(tagName);

      for (var j = 0; j &lt; tagElements.length; j++)

        elements.push(tagElements[j]);

    }

    return elements;

  },

//有一个满足就返回


    form = $(form);

    var inputs = form.getElementsByTagName('input');

    if (!typeName &amp;&amp; !name)

      return inputs;

    var matchingInputs = new Array();

    for (var i = 0; i &lt; inputs.length; i++) {

      var input = inputs[i];

      if ((typeName &amp;&amp; input.type != typeName) ||

          (name &amp;&amp; input.name != name))

        continue;

      matchingInputs.push(input);

    }

    return matchingInputs;

  },

//整个表单域禁用


    var elements = Form.getElements(form);

    for (var i = 0; i &lt; elements.length; i++) {

      var element = elements[i];

      element.blur();

      element.disabled = 'true';

    }

  },

//启用


    var elements = Form.getElements(form);

    for (var i = 0; i &lt; elements.length; i++) {

      var element = elements[i];

      element.disabled = '';

    }

  },

//获取第一个可用的表单域


    return Form.getElements(form).find(function(element) {

      return element.type != 'hidden' &amp;&amp; !element.disabled &amp;&amp;

        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());

    });

  },

//激活第一个表单域


    Field.activate(Form.findFirstElement(form));

  },

    $(form).reset();

  }

}

//【Form.Element】 对特定的表单域进行操作


Form.Element = {

//序列化形成&quot;&amp;name=value&quot;


    element = $(element);

    var method = element.tagName.toLowerCase();

    var parameter = Form.Element.Serializers[method](element);

    if (parameter) {

      var key = encodeURIComponent(parameter[0]);

      if (key.length == 0) return;

      if (parameter[1].constructor != Array)

        parameter[1] = [parameter[1]];

      return parameter[1].map(function(value) {

        return key + '=' + encodeURIComponent(value);

      }).join('&amp;');

    }

  },

//获得指定表单域的值


    element = $(element);

    var method = element.tagName.toLowerCase();

    var parameter = Form.Element.Serializers[method](element);

    if (parameter)

      return parameter[1];

  }

}

//【Form.Element.Serializers】针对不同的表单域进行序列化


Form.Element.Serializers = {

//一般用所有的&lt;input&gt;标记的序列化都可以


    switch (element.type.toLowerCase()) {

                        return Form.Element.Serializers.textarea(element);

                return Form.Element.Serializers.inputSelector(element);

    }

    return false;

  },

    if (element.checked)

      return [element.name, element.value];

  },

    return [element.name, element.value];

  },

    return Form.Element.Serializers[element.type == 'select-one' ?

     

  },

    var value = '', opt, index = element.selectedIndex;

    if (index &gt;= 0) {

      opt = element.options[index];

      value = opt.value;

      if (!value &amp;&amp; !('value' in opt))

        value = opt.text;

    }

    return [element.name, value];

  },

    var value = new Array();

    for (var i = 0; i &lt; element.length; i++) {

      var opt = element.options[i];

      if (opt.selected) {

        var optValue = opt.value;

        if (!optValue &amp;&amp; !('value' in opt))

          optValue = opt.text;

        value.push(optValue);

      }

    }

    return [element.name, value];

  }

}

//【获得表单域的值】


var $F = Form.Element.getValue;

/*========================================================================================*/


</pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227099#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 17:08:49 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227099</link>
        <guid>http://dmewy.javaeye.com/blog/227099</guid>
      </item>
      <item>
        <title>Prototype 1.4.0 源码解读----全文注释版(上)</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227098" style="color:red;">http://dmewy.javaeye.com/blog/227098</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="js">* Prototype JavaScript framework, version 1.4.0

 * (c) 2005 Sam Stephenson &lt;sam@conio.net&gt;

 *

 * Prototype is freely distributable under the terms of an MIT-style license.

 * For details, see the Prototype web site: http://prototype.conio.net/


 

 * 这是一个JavaScript的框架,致力于简化动态的Web开发，完全按照面对对象的思想

 * 进行Javascript开发，添加了迭代器的概念增强Javascript的设计能力。

 * Prototype框架构思独特充满了技巧性的代码，方便易用的工具类！

 *

/*--------------------------------------------------------------------------*/

 

  

/* 【Prototype】定义一个全局对象,提供一个全局的基本信息和工具 */

var Prototype = {

  Version: '1.4.0', //可以作为版本检测用


//用于脚本检测的正则表达式，经常使用所以放在这里起到全局常量的作用


  ScriptFragment: '(?:&lt;script.*?&gt;)((\n|\r|.)*?)(?:&lt;\/script&gt;)',

  emptyFunction: function() {},//空函数


  K: function(x) {return x}//K方法返回参数本身，在后面经常用到


}

/*========================================================================================*/

/*

 *【Class】对象的作用只有一个就是提供了一个定义类的模式

 * 仅含有create 一个方法，返回一个构造函数。

 * 一般使用如下

 * var X = Class.create(); 返回一个类型

 * 要使用 X 类型，需继续用 new X()来获取一个实例 这与C# JAVA类似

 * 返回的构造函数会执行名为 initialize 的方法， initialize 是 Ruby 对象的构造器方法名字。

 * 此时initialize方法还没有定义，其后的代码中创建新类型时会建立相应的同名方法,可以看作是一个抽象方法。

 * 从C#角度讲可以理解为用Class.create()创建一个继承Object基类的类。

 *

 */

var Class = {

  create: function() {

    return function() { //下面使用Apply方法传递参数是一个常用的技巧


      this.initialize.apply(this, arguments);

    }

  }

}

/*========================================================================================*/

//Abstract是一个空对象，它的作用仅仅是作为一个抽象的命名空间，所有在该对象下定义的类都是抽象类


//从而从形式上与实体类分开


var Abstract = new Object();

/*

 *Object是所有对象的基类，这个基类有两个静态方法

 */

//把Source的所有属性和方法传递给Destination，实现了继承的效果


Object.extend = function(destination, source) {

  for (property in source) {

    destination[property] = source[property];

  }

  return destination;

}

//观察Object的组成，需要参数中的object实现自己的inspect方法


Object.inspect = function(object) {

  try {

    if (object == undefined) return 'undefined';

    if (object == null) return 'null';

    return object.inspect ? object.inspect() : object.toString();

  } catch (e) {

    if (e instanceof RangeError) return '';

    throw e;

  }

}

/*========================================================================================*/

//【Function】是所有函数对象的基类，可以通过对它的扩展实现对所有函数对象添加功能


/* 这里在绑定的时候旧可以传递参数而不是调用的时候才指定参数，bind方法接收多个参数

  将函数绑定到第一个参数指定的对象上，并返回该方法的调用句柄

*/

Function.prototype.bind = function() {

  // $A()方法的作用是把参数专为数组


  //数组的shift方法作用是删除数组的第一个元素


  var __method = this, args = $A(arguments), object = args.shift();

  return function() {

    return __method.apply(object, args.concat($A(arguments)));

    //这里的$A(arguments)是条用返回函数句柄时传递的参数，不是bind方法的参数


  }

}

/**

 * 和bind一样，不过这个方法一般用做html控件对象的事件处理。所以要传递event对象

 * 好像是重载了_method方法

 */

Function.prototype.bindAsEventListener = function(object) {

  var __method = this;

  return function(event) {

    return __method.call(object, event || window.event);

  }

}

/*========================================================================================*/

//【Function】是所有数值类型的基类


Object.extend(Number.prototype, {

  toColorPart: function() { //RGB-》16进制颜色


    var digits = this.toString(16);

    if (this &lt; 16) return '0' + digits;

    return digits;

  },

  succ: function() { //数值加一 var a=1; var b=a.succ; 那么b=2


    return this + 1;

  },

  times: function(iterator) {

  //这里的参数iterator是一个迭代器作用就是循环调用指定次数的iterator函数


  //$R(start,end,exclusive)是创建ObjectRnge对象的快捷方式


    $R(0, this, true).each(iterator);

    return this;

  }

});

/*========================================================================================*/

//提供了一个方法these，要求参数是函数的句柄，可以有多个。作用就是返回第一个成功执行的函数的返回值


var Try = {

  these: function() {

    var returnValue;

    for (var i = 0; i &lt; arguments.length; i++) {

      var lambda = arguments[i];

      try {

        returnValue = lambda();

        break;

      } catch (e) {}

    }

    return returnValue;

  }

}

/*========================================================================================*/

//定时器类用来实现Window.setInterval的效果，在给定时间间隔执行某一个函数，增加了对重复执行的控制S


var PeriodicalExecuter = Class.create();

PeriodicalExecuter.prototype = {

  initialize: function(callback, frequency) {

  //构造函数指定回调函数和执行频率，单位是秒


    this.callback = callback;

    this.frequency = frequency;

    this.currentlyExecuting = false;

    this.registerCallback();

  },

  

/* 开始调用定时器，无需显示调用，在构造函数中就实现了自动调用，这一下面的

this.onTimerEvent.bind(this)如果写成this.onTimerEvent则this指针就会指向widows对象即setInterval的默认对象

从而不能正确的引用到下面两个函数上，也就失去了对正在执行函数的控制

*/

  registerCallback: function() {

    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);

  },

//下面的函数相当于是回调函数的一个代理， setInterval是到了指定的时间就会强制执行而这里


//加入了一个判断如果callback函数执行的时间超过了一个时间片，则阻止其被重复执行


  onTimerEvent: function() {

    if (!this.currentlyExecuting) {

      try {

        this.currentlyExecuting = true;

        this.callback();

      } finally {

        this.currentlyExecuting = false;

      }

    }

  }

}

/*使用举例：

function GetOnlineCount()

{//获得在线人数

}

new PeriodicalExecuter(GetOnlineCount,10)每10秒获取一次

*/

/*========================================================================================*/

/* 框架核心内容--------【基础工具类】

/*========================================================================================*/

 /*document.getElementById(id)获取一个指定ID的结点,是这个方法的快捷方式和扩展

 可以指定多个参数返回一个对象数组。参数也不一定是ID也可以是对象本身的引用，例如

 $('id')等价于$($('id'))

  */

function $() {

  var elements = new Array();

  for (var i = 0; i &lt; arguments.length; i++) {

    var element = arguments[i];

    if (typeof element == 'string')

      element = document.getElementById(element);

    if (arguments.length == 1)

      return element;

    elements.push(element);

  }

  return elements;

}

/*========================================================================================*/

//【String】类的扩展


//删除字符串中的HTML标记


Object.extend(String.prototype, {

  stripTags: function() {

    return this.replace(/&lt;\/?[^&gt;]+&gt;/gi, '');

  },

//删除字符串中的脚本块


  stripScripts: function() {

    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');

  },

//提取字符串中的所有脚本块，作为数组返回，每一个脚本作为一个数组元素


  extractScripts: function() {

    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');

    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');

    return (this.match(matchAll) || []).map(function(scriptTag) {

      return (scriptTag.match(matchOne) || ['', ''])[1];

    });

  },

//提取字符串中的脚本并执行


  evalScripts: function() {

    return this.extractScripts().map(eval);

  },

//将字符串进行html编码例如&quot;&lt;&quot; --》&quot;&lt;&quot;


  escapeHTML: function() {

    var div = document.createElement('div');

    var text = document.createTextNode(this);

    div.appendChild(text);

    return div.innerHTML;

  },

//对字符串进行html解码例如&quot;&lt;&quot;--》&quot;&lt;&quot;


  unescapeHTML: function() {

    var div = document.createElement('div');

    div.innerHTML = this.stripTags();

    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';

  },

//将查询字符串格式的字符串转换为键值对数组


//例如var s=&quot;a=1&amp;b=2&amp;c=3&quot;; var s2=s.toQueryParams(); s2为{a:1,b:2,c:3}


  toQueryParams: function() {

    var pairs = this.match(/^\??(.*)$/)[1].split('&amp;');

    return pairs.inject({}, function(params, pairString) {

      var pair = pairString.split('=');

      params[pair[0]] = pair[1];

      return params;

    });

  },

//字符串转换为字符数组 &quot;abc&quot;--&gt;['a','b','c']


  toArray: function() {

    return this.split('');

  },

//连字符--》骆驼样式 'good-man'--&gt;'goodMan'


  camelize: function() {

    var oStringList = this.split('-');

    if (oStringList.length == 1) return oStringList[0];

    var camelizedString = this.indexOf('-') == 0

      ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)

      : oStringList[0];

    for (var i = 1, len = oStringList.length; i &lt; len; i++) {

      var s = oStringList[i];

      camelizedString += s.charAt(0).toUpperCase() + s.substring(1);

    }

    return camelizedString;

  },

//得到字符串的组成结构


  inspect: function() {

    return &quot;'&quot; + this.replace('\\', '\\\\').replace(&quot;'&quot;, '\\\'') + &quot;'&quot;;

  }

});

//定义了一个等价的函数


String.prototype.parseQuery = String.prototype.toQueryParams;

/*========================================================================================*/

//【Enumerable】可枚举接口 是整个1.4.0框架的核心工具，所有实现此接口的类必须要实现_each(iterator)方法


var $break = new Object(); //首先定义了两个异常对象，用于进行迭代计算的控制


var $continue = new Object();

var Enumerable = {

//用于对对象的每一个元素遍历执行iterator迭代器函数


  each: function(iterator) {

    var index = 0; //可选参数表示元素在枚举对象的次序


    try {

      this._each(function(value) {//value是枚举元素的值


        try {

          iterator(value, index++);

        } catch (e) {

          if (e != $continue) throw e;

        }

      });

    } catch (e) {

      if (e != $break) throw e;

    }

  },

//判断是否所有的枚举元素都能使iterator返回true


  all: function(iterator) {

    var result = true;

    this.each(function(value, index) {

      result = result &amp;&amp; !!(iterator || Prototype.K)(value, index);

      if (!result) throw $break;

    });

    return result;

  },

//判断是否有枚举元素能使iterator返回true，有一个就是True


  any: function(iterator) {

    var result = true;

    this.each(function(value, index) {

      if (result = !!(iterator || Prototype.K)(value, index))

        throw $break;

    });

    return result;

  },

//对所有的枚举元素执行iterator迭代器函数 结果作为一个数组返回


  collect: function(iterator) {

    var results = [];

    this.each(function(value, index) {

      results.push(iterator(value, index));

    });

    return results;

  },

//第一个素能使iterator返回true的枚举元素的值，没有返回undefined


  detect: function (iterator) {

    var result;

    this.each(function(value, index) {

      if (iterator(value, index)) {

        result = value;

        throw $break;

      }

    });

    return result;

  },

//找到所有的能使iterator迭代器函数返回true的枚举元素 作为一个数组返回


  findAll: function(iterator) {

    var results = [];

    this.each(function(value, index) {

      if (iterator(value, index))

        results.push(value);

    });

    return results;

  },

//找到素有匹配pattern的枚举元素，结果作为数组返回，iterator可选，如果不指定旧返回素有匹配pattern的枚举元素


  grep: function(pattern, iterator) {//正则模式 迭代器


    var results = [];

    this.each(function(value, index) {

      var stringValue = value.toString();

      if (stringValue.match(pattern))

        results.push((iterator || Prototype.K)(value, index));

    })

    return results;

  },

//判断枚举对象中是否含有参数Object指定的值


  include: function(object) {

    var found = false;

    this.each(function(value) {

      if (value == object) {

        found = true;

        throw $break;

      }

    });

    return found;

  },

//将memo作为iterator的第一个参数，枚举元素作为iterator的第二个参数，枚举元素的次序作为第三个


//参数每次迭代器的返回值将作为下一个iterator的memo参数，从而所有的迭代执行都通过memo联系起来了


  inject: function(memo, iterator) {

    this.each(function(value, index) {

      memo = iterator(memo, value, index);

    });

    return memo;

  },

//对所有的枚举元素执行method方法 后面是要传递的参数


  invoke: function(method) {

    var args = $A(arguments).slice(1);

    return this.collect(function(value) {

      return value[method].apply(value, args);

    });

  },

//返回的最大的迭代器执行结果


  max: function(iterator) {

    var result;

    this.each(function(value, index) {

      value = (iterator || Prototype.K)(value, index);

      if (value &gt;= (result || value))

        result = value;

    });

    return result;

  },

//反之


  min: function(iterator) {

    var result;

    this.each(function(value, index) {

      value = (iterator || Prototype.K)(value, index);

      if (value &lt;= (result || value))

        result = value;

    });

    return result;

  },

//返回两个数组一组能使iterator返回true 另一组返回false


  partition: function(iterator) {

    var trues = [], falses = [];

    this.each(function(value, index) {

      ((iterator || Prototype.K)(value, index) ?

        trues : falses).push(value);

    });

    return [trues, falses];

  },

//获取所有枚举元素的property属性值作为数组的返回


  pluck: function(property) {

    var results = [];

    this.each(function(value, index) {

      results.push(value[property]);

    });

    return results;

  },

//与findall相反


  reject: function(iterator) {

    var results = [];

    this.each(function(value, index) {

      if (!iterator(value, index))

        results.push(value);

    });

    return results;

  },

//根据iterator的结果排序 最小的在前面 作为数组返回


  sortBy: function(iterator) {

    return this.collect(function(value, index) {

      return {value: value, criteria: iterator(value, index)};

    }).sort(function(left, right) {

      var a = left.criteria, b = right.criteria;

      return a &lt; b ? -1 : a &gt; b ? 1 : 0;

    }).pluck('value');

  },

//枚举对象--》数组


  toArray: function() {

    return this.collect(Prototype.K);

  },

//接收多个枚举对象参数，最后一个可以是迭代器用于阵列转换


  zip: function() {

    var iterator = Prototype.K, args = $A(arguments);

    if (typeof args.last() == 'function')

      iterator = args.pop();

    var collections = [this].concat(args).map($A);

    return this.map(function(value, index) {

      iterator(value = collections.pluck(index));

      return value;

    });

  },

//返回枚举对象的字符串描述


  inspect: function() {

    return '#&lt;Enumerable:' + this.toArray().inspect() + '&gt;';

  }

}

//等价函数定义


Object.extend(Enumerable, {

  map: Enumerable.collect,

  find: Enumerable.detect,

  select: Enumerable.findAll,

  member: Enumerable.include,

  entries: Enumerable.toArray

});

/*========================================================================================*/

//【Array】数组对象


//参数转换为数组，如果参数定义了toarray则直接调用，否则枚举获得数组


var $A = Array.from = function(iterable) {

  if (!iterable) return [];

  if (iterable.toArray) {

    return iterable.toArray();

  } else {

    var results = [];

    for (var i = 0; i &lt; iterable.length; i++)

      results.push(iterable[i]);

    return results;

  }

}

//数组对象继承了Enumerable接口


Object.extend(Array.prototype, Enumerable);

Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {

//实现了枚举接口方法，用于对数组内的元素执行迭代器


  _each: function(iterator) {

    for (var i = 0; i &lt; this.length; i++)

      iterator(this[i]);

  },

//清空数组


  clear: function() {

    this.length = 0;

    return this;

  },

//取得第一个元素


  first: function() {

    return this[0];

  },

//取得最后一个元素


  last: function() {

    return this[this.length - 1];

  },

//删除数组元素中所有的null undefined值 作为新数组返回，原数组不受影响


  compact: function() {

    return this.select(function(value) {

      return value != undefined || value != null;

    });

  },

//展开所有数组元素不再嵌套


  flatten: function() {

    return this.inject([], function(array, value) {

      return array.concat(value.constructor == Array ?

        value.flatten() : [value]);

    });

  },

//数组中删除指定的元素，返回删除后的结果，原数组不受影响


  without: function() {

    var values = $A(arguments);

    return this.select(function(value) {

      return !values.include(value);

    });

  },

//Value元素在数组中的索引值


  indexOf: function(object) {

    for (var i = 0; i &lt; this.length; i++)

      if (this[i] == object) return i;

    return -1;

  },

//反转数组


  reverse: function(inline) {

    return (inline !== false ? this : this.toArray())._reverse();

  },

//删除数组中第一个元素并返回这个元素的值


  shift: function() {

    var result = this[0];

    for (var i = 0; i &lt; this.length - 1; i++)

      this[i] = this[i + 1];

    this.length--;

    return result;

  },

//得到数组的字符串描述例如arr=[1,2,3]-----&gt; &quot;[1,2,3]&quot;


  inspect: function() {

    return '[' + this.map(Object.inspect).join(', ') + ']';

  }

});

/*========================================================================================*/

//【Hash】哈希对象


var Hash = {

//实现枚举接口方法从而使Hash对象也是枚举对象


  _each: function(iterator) {

    for (key in this) {

      var value = this[key];

      if (typeof value == 'function') continue;

      var pair = [key, value];

      pair.key = key;

      pair.value = value;

      iterator(pair);

    }

  },

//所有键数组


  keys: function() {

    return this.pluck('key');

  },

//所有值数组


  values: function() {

    return this.pluck('value');

  },

//合并哈希表，键相同就覆盖调用者


  merge: function(hash) {

    return $H(hash).inject($H(this), function(mergedHash, pair) {

      mergedHash[pair.key] = pair.value;

      return mergedHash;

    });

  },

//键值对组成查询字符串的形式


  toQueryString: function() {

    return this.map(function(pair) {

      return pair.map(encodeURIComponent).join('=');

    }).join('&amp;');

  },

//获取Hash对象的字符串描述


  inspect: function() {

    return '#&lt;Hash:{' + this.map(function(pair) {

      return pair.map(Object.inspect).join(': ');

    }).join(', ') + '}&gt;';

  }

}

/*哈希表不是类而是对象所以不能用new的方法创建，而是用$H()函数

  这个方法吧一个对象转换为哈希对象，对象的属性名为key 值为value

  可枚举！！

*/

function $H(object) {

  var hash = Object.extend({}, object || {});

  Object.extend(hash, Enumerable);

  Object.extend(hash, Hash);

  return hash;

}

/*========================================================================================*/

//【ObjectRange】用于进行指定次数的循环运算，同样继承于枚举接口并实现_each方法


//有了这个方法基本上Javascript里面就不用for循环了


ObjectRange = Class.create();

Object.extend(ObjectRange.prototype, Enumerable);

Object.extend(ObjectRange.prototype, {

//构造函数同事指定了3个参数的值


  initialize: function(start, end, exclusive) {

    this.start = start; //其实索引


    this.end = end;//结束索引


    this.exclusive = exclusive;//表示是否包含结束索引


  },

  _each: function(iterator) {

    var value = this.start;

    do {

      iterator(value);

      value = value.succ();

    } while (this.include(value));

  },

//重写枚举接口的include方法，判断改循环的索引是否包含参数value的指定的值


  include: function(value) {

    if (value &lt; this.start)

      return false;

    if (this.exclusive)

      return value &lt; this.end;

    return value &lt;= this.end;

  }

});

//使用$R()方法快速创建objectRange对象


var $R = function(start, end, exclusive) {

  return new ObjectRange(start, end, exclusive);

}

/*========================================================================================*/
</pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227098#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 17:06:41 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227098</link>
        <guid>http://dmewy.javaeye.com/blog/227098</guid>
      </item>
      <item>
        <title>JXL入门介绍</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227092" style="color:red;">http://dmewy.javaeye.com/blog/227092</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java"># package com.xinli;   
# import java.io.FileOutputStream;   
# import java.io.OutputStream;   
# import java.text.SimpleDateFormat;   
# import java.util.ArrayList;   
# import java.util.Date;   
# import java.util.List;   
#   
# import jxl.*;   
# import jxl.format.Alignment;   
# import jxl.format.Border;   
# import jxl.format.BorderLineStyle;   
# import jxl.format.CellFormat;   
# import jxl.write.Boolean;   
# import jxl.write.Label;   
# import jxl.write.Number;   
# import jxl.write.WritableCellFormat;   
# import jxl.write.WritableFont;   
# import jxl.write.WritableSheet;   
# import jxl.write.WritableWorkbook;   
#   
# public class JXLExample {   
#   
#     /**
#       *
#       * @author smart      *
#       */  
#     public static void main(String[] args) {   
#         // 准备设置excel工作表的标题   
#          String[] title = {&quot;编号&quot;,&quot;产品名称&quot;,&quot;产品价格&quot;,&quot;产品数量&quot;,&quot;生产日期&quot;,&quot;产地&quot;,&quot;是否出口&quot;};   
#         try {   
#             // 获得开始时间   
#             long start = System.currentTimeMillis();   
#             // 输出的excel的路径   
#              String filePath = &quot;c:\\test.xls&quot;;   
#             // 创建Excel工作薄   
#              WritableWorkbook wwb;   
#             // 新建立一个jxl文件,即在C盘下生成test.xls   
#              OutputStream os = new FileOutputStream(filePath);   
#              wwb=Workbook.createWorkbook(os);   
#             // 添加第一个工作表并设置第一个Sheet的名字   
#              WritableSheet sheet = wwb.createSheet(&quot;产品清单&quot;, 0);   
#              Label label;   
#             for(int i=0;i&lt;title.length;i++){   
#                 // Label(x,y,z)其中x代表单元格的第x+1列，第y+1行, 单元格的内容是y   
#                 // 在Label对象的子对象中指明单元格的位置和内容   
#                  label = new Label(i,0,title[i]);   
#                 // 将定义好的单元格添加到工作表中   
#                  sheet.addCell(label);   
#              }   
#             // 下面是填充数据   
#             /*
#               * 保存数字到单元格，需要使用jxl.write.Number
#               * 必须使用其完整路径，否则会出现错误
#               * */  
#             // 填充产品编号   
#             jxl.write.Number number = new jxl.write.Number(0,1,20071001);   
#              sheet.addCell(number);   
#             // 填充产品名称   
#              label = new Label(1,1,&quot;金鸽瓜子&quot;);   
#              sheet.addCell(label);   
#             /*
#               * 定义对于显示金额的公共格式
#               * jxl会自动实现四舍五入
#               * 例如 2.456会被格式化为2.46,2.454会被格式化为2.45
#               * */  
#             jxl.write.NumberFormat nf = new jxl.write.NumberFormat(&quot;#.##&quot;);   
#             jxl.write.WritableCellFormat wcf = new jxl.write.WritableCellFormat(nf);   
#             // 填充产品价格   
#             jxl.write.Number nb = new jxl.write.Number(2,1,2.45,wcf);   
#              sheet.addCell(nb);   
#             // 填充产品数量   
#             jxl.write.Number numb = new jxl.write.Number(3,1,200);   
#              sheet.addCell(numb);   
#             /*
#               * 定义显示日期的公共格式
#               * 如:yyyy-MM-dd hh:mm
#               * */  
#              SimpleDateFormat sdf = new SimpleDateFormat(&quot;yyyy-MM-dd&quot;);   
#              String newdate = sdf.format(new Date());   
#             // 填充出产日期   
#              label = new Label(4,1,newdate);   
#              sheet.addCell(label);   
#             // 填充产地   
#              label = new Label(5,1,&quot;陕西西安&quot;);   
#              sheet.addCell(label);   
#             /*
#               * 显示布尔值
#               * */  
#             jxl.write.Boolean bool = new jxl.write.Boolean(6,1,true);   
#              sheet.addCell(bool);   
#             /*
#               * 合并单元格
#               * 通过writablesheet.mergeCells(int x,int y,int m,int n);来实现的
#               * 表示将从第x+1列，y+1行到m+1列，n+1行合并
#               *
#               * */  
#              sheet.mergeCells(0,3,2,3);   
#              label = new Label(0,3,&quot;合并了三个单元格&quot;);   
#              sheet.addCell(label);   
#             /*
#               *
#               * 定义公共字体格式
#               * 通过获取一个字体的样式来作为模板
#               * 首先通过web.getSheet(0)获得第一个sheet
#               * 然后取得第一个sheet的第二列，第一行也就是&quot;产品名称&quot;的字体
#               * */  
#              CellFormat cf = wwb.getSheet(0).getCell(1, 0).getCellFormat();   
#              WritableCellFormat wc = new WritableCellFormat();   
#             // 设置居中   
#              wc.setAlignment(Alignment.CENTRE);   
#             // 设置边框线   
#              wc.setBorder(Border.ALL, BorderLineStyle.THIN);   
#             // 设置单元格的背景颜色   
#              wc.setBackground(jxl.format.Colour.RED);   
#              label = new Label(1,5,&quot;字体&quot;,wc);   
#              sheet.addCell(label);   
#   
#             // 设置字体   
#             jxl.write.WritableFont wfont = new jxl.write.WritableFont(WritableFont.createFont(&quot;隶书&quot;),20);   
#              WritableCellFormat font = new WritableCellFormat(wfont);   
#              label = new Label(2,6,&quot;隶书&quot;,font);   
#              sheet.addCell(label);   
#                
#             // 写入数据   
#              wwb.write();   
#             // 关闭文件   
#              wwb.close();   
#             long end = System.currentTimeMillis();   
#              System.out.println(&quot;----完成该操作共用的时间是:&quot;+(end-start)/1000);   
#          } catch (Exception e) {   
#              System.out.println(&quot;---出现异常---&quot;);   
#              e.printStackTrace();   
#          }   
#      }   
#   
# } </pre>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227092#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 16:57:12 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227092</link>
        <guid>http://dmewy.javaeye.com/blog/227092</guid>
      </item>
      <item>
        <title>jxl 操作(读,写) Excel 例子</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227089" style="color:red;">http://dmewy.javaeye.com/blog/227089</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span class="javascript" style="font-size: 12px;"><span style="font-family: Verdana;">jxl不错，简单易用<br />
<br />
</span>
</span>
</p>
<pre name="code" class="java">import jxl.*;
import jxl.write.*;
import java.io.*;
import java.io.File.*;
import java.util.*;



public class excel
{
public static void main(String[] args) 
{

String targetfile = &quot;c:/out.xls&quot;;//输出的excel文件名
String worksheet = &quot;List&quot;;//输出的excel文件工作表名
String[] title = {&quot;ID&quot;,&quot;NAME&quot;,&quot;DESCRIB&quot;};//excel工作表的标题


WritableWorkbook workbook;
try
{
//创建可写入的Excel工作薄,运行生成的文件在tomcat/bin下
//workbook = Workbook.createWorkbook(new File(&quot;output.xls&quot;)); 
System.out.println(&quot;begin&quot;);

OutputStream os=new FileOutputStream(targetfile); 
workbook=Workbook.createWorkbook(os); 

WritableSheet sheet = workbook.createSheet(worksheet, 0); //添加第一个工作表
//WritableSheet sheet1 = workbook.createSheet(&quot;MySheet1&quot;, 1); //可添加第二个工作
/*
jxl.write.Label label = new jxl.write.Label(0, 2, &quot;A label record&quot;); //put a label in cell A3, Label(column,row)
sheet.addCell(label); 
*/

jxl.write.Label label;
for (int i=0; i&lt;title.length; i++)
{
//Label(列号,行号 ,内容 )
label = new jxl.write.Label(i, 0, title[i]); //put the title in row1 
sheet.addCell(label); 
}




//下列添加的对字体等的设置均调试通过，可作参考用


//添加数字
jxl.write.Number number = new jxl.write.Number(3, 4, 3.14159); //put the number 3.14159 in cell D5
sheet.addCell(number);

//添加带有字型Formatting的对象 
jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES,10,WritableFont.BOLD,true); 
jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf); 
jxl.write.Label labelCF = new jxl.write.Label(4,4,&quot;文本&quot;,wcfF); 
sheet.addCell(labelCF); 

//添加带有字体颜色,带背景颜色 Formatting的对象 
jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL,10,WritableFont.BOLD,false,jxl.format.UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.RED); 
jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc); 
wcfFC.setBackground(jxl.format.Colour.BLUE);
jxl.write.Label labelCFC = new jxl.write.Label(1,5,&quot;带颜色&quot;,wcfFC); 
sheet.addCell(labelCFC); 

//添加带有formatting的Number对象 
jxl.write.NumberFormat nf = new jxl.write.NumberFormat(&quot;#.##&quot;); 
jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf); 
jxl.write.Number labelNF = new jxl.write.Number(1,1,3.1415926,wcfN); 
sheet.addCell(labelNF); 

//3.添加Boolean对象 
jxl.write.Boolean labelB = new jxl.write.Boolean(0,2,false); 
sheet.addCell(labelB); 

//4.添加DateTime对象 
jxl.write.DateTime labelDT = new jxl.write.DateTime(0,3,new java.util.Date()); 
sheet.addCell(labelDT); 

//添加带有formatting的DateFormat对象 
jxl.write.DateFormat df = new jxl.write.DateFormat(&quot;ddMMyyyyhh:mm:ss&quot;); 
jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df); 
jxl.write.DateTime labelDTF = new jxl.write.DateTime(1,3,new java.util.Date(),wcfDF); 
sheet.addCell(labelDTF); 

//和宾单元格
//sheet.mergeCells(int col1,int row1,int col2,int row2);//左上角到右下角
sheet.mergeCells(4,5,8,10);//左上角到右下角
wfc = new jxl.write.WritableFont(WritableFont.ARIAL,40,WritableFont.BOLD,false,jxl.format.UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.GREEN); 
jxl.write.WritableCellFormat wchB = new jxl.write.WritableCellFormat(wfc); 
wchB.setAlignment(jxl.format.Alignment.CENTRE);
labelCFC = new jxl.write.Label(4,5,&quot;单元合并&quot;,wchB); 
sheet.addCell(labelCFC); //


//设置边框
jxl.write.WritableCellFormat wcsB = new jxl.write.WritableCellFormat(); 
wcsB.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THICK);
labelCFC = new jxl.write.Label(0,6,&quot;边框设置&quot;,wcsB); 
sheet.addCell(labelCFC); 
workbook.write(); 
workbook.close();
}catch(Exception e) 
{ 
e.printStackTrace(); 
} 
System.out.println(&quot;end&quot;);
Runtime r=Runtime.getRuntime(); 
Process p=null; 
//String cmd[]={&quot;notepad&quot;,&quot;exec.java&quot;}; 
String cmd[]={&quot;C:\\Program Files\\Microsoft Office\\Office\\EXCEL.EXE&quot;,&quot;out.xls&quot;}; 
try{ 
p=r.exec(cmd); 
} 
catch(Exception e){ 
System.out.println(&quot;error executing: &quot;+cmd[0]); 
}


}
}</pre>
&nbsp;
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227089#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 16:56:15 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227089</link>
        <guid>http://dmewy.javaeye.com/blog/227089</guid>
      </item>
      <item>
        <title>JXL--Excel使用笔记</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227085" style="color:red;">http://dmewy.javaeye.com/blog/227085</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">读Excel:

Workbook workbook = null;

  try
  {
      workbook = Workbook.getWorkbook(new File(path));
  }
  catch(Exception e)
  {
   System.out.println(e);
  }

Sheet sheet = workbook.getSheet(0);
Cell cell=sheet.getCell(i,j);//读第i列，第j行表格的值
System.out.println(cell.getContents());
对于循环读出可以使用
sheet.getRows();方法得到行数
sheet.getColumns();方法得到列数

写Excel:

Workbook wb = Workbook.getWorkbook(new File(path));

WritableCellFormat wcf = new WritableCellFormat();

book = Workbook.createWorkbook(new File(path, wb);
sheet = book.getSheet(0);
jxl.write.Label name = new jxl.write.Label(i,j,&quot;abc&quot;,wcf);//在第i列，第j行写入&quot;abc&quot;值，风格为wcf，如果写入的是数字则使用jxl.write.Number
sheet.addCell(name);
try
   {
    book.write();
    book.close();
   }
   catch(WriteException e){}
   catch(IOException e){}

单元格风格:

设置边框—
WritableCellFormat wcf = new WritableCellFormat();
wcf.setVerticalAlignment(VerticalAlignment.CENTRE);
wcf.setBorder(Border.RIGHT,BorderLineStyle.THIN);
wcf.setBorder(Border.LEFT,BorderLineStyle.THIN);
wcf.setBorder(Border.BOTTOM,BorderLineStyle.THIN);

合并单元格-
sheet.mergeCells(0,1,0,2)
合并(0,1)、(0,2)两个单元格

设置字体-
WritableFont wf = new WritableFont(WritableFont.ARIAL,12, WritableFont.BOLD, false);
WritableCellFormat wcf = new WritableCellFormat(wf);
以及其它各种单元格样式，如设置背景颜色
都可以通过设置WritableCellFormat来设置
</pre>
&nbsp;
<p><span style="font-size: 8pt; font-family: Arial;"><span style="font-family: Arial;"><span style="font-size: 10pt;"><br />
</span>
</span>
</span>
</p>
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227085#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 16:55:06 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227085</link>
        <guid>http://dmewy.javaeye.com/blog/227085</guid>
      </item>
      <item>
        <title>使用JXL读取Excel表格,拷贝、更新Excel工作薄</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/227084" style="color:red;">http://dmewy.javaeye.com/blog/227084</a>&nbsp;
          发表时间: 2008年08月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">/**
* &lt;p&gt;读取Excel表格,拷贝、更新Excel工作薄 &lt;/p&gt;
* &lt;p&gt;Description: 可以读取Excel文件的内容,更新Excel工作薄
* &lt;/p&gt;
* &lt;p&gt;Copyright: Copyright (c) Corparation 2005&lt;/p&gt;
* &lt;p&gt;程序开发环境为eclipse&lt;/p&gt;
* @author Walker
* @version 1.0
*/
package cn.com.yitong.xls;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Vector;

import cn.com.yitong.ChartImg;
import cn.com.yitong.VireObj;
import cn.com.yitong.platform.log.YTLogger;

import jxl.CellType;
import jxl.Workbook;
import jxl.format.CellFormat;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.Formula;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableImage;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

public class XLSDemo
{
    private static final int TITLE_LENGTH = 7;
    private static final int SHEET_WIDTH = 32;
    private static final int SHEET_HEIGHT = 116;
    
    /**
     * 创建Excel
     */
    private void makeXls()
    {
        Workbook workbook = null;
        try
        {
            // 构建Workbook对象, 只读Workbook对象
            // 直接从本地文件创建Workbook, 从输入流创建Workbook
            InputStream ins = new FileInputStream(&quot;D:/Workspace/testproj/source.xls&quot;);
            workbook = Workbook.getWorkbook(ins);

            // 利用已经创建的Excel工作薄创建新的可写入的Excel工作薄
            File outFile = new File(&quot;D:/Workspace/testproj/test.xls&quot;);
            WritableWorkbook wwb = Workbook.createWorkbook(outFile, workbook);
            // 读取第一张工作表
            WritableSheet dataSheet = wwb.getSheet(0);
            //  设置冻结单元格
            dataSheet.getSettings().setVerticalFreeze(7);
            dataSheet.getSettings().setHorizontalFreeze(2);
            
            // 测试模拟数据
            Vector vecData = new Vector();
            for(int i = 0; i &lt; 50; i ++)
            {
                VireObj obj = new VireObj();
                obj.setOrgNo(&quot;00&quot; + i + &quot;0&quot;);
                obj.setOrgName(&quot;机构&quot; + (i + 1));
                obj.setOpenAcc((int)(100 * Math.random()));
                obj.setDestoryAcc((int)(10 * Math.random()));
                obj.setTotalAcc((int)(500 * Math.random()));
                obj.setMonthInCount((int)(500 * Math.random()));
                obj.setMonthInMoney(500 * Math.random());
                obj.setMonthOutCount((int)(500 * Math.random()));
                obj.setMonthOutMoney(500 * Math.random());
                
                vecData.add(obj);
            }            
            // 插入数据
            insertData(wwb, dataSheet, vecData);            
            // 插入模拟图像数据
            Vector vecImg = new Vector();
            for(int i = 0; i &lt; 3; i ++)
            {
                ChartImg img = new ChartImg();
                img.setImgTitle(&quot;图像&quot; + (i + 1));
                img.setImgName(&quot;D:/Workspace/testproj/images/barchart.png&quot;);
                vecImg.add(img);
            }
            // 插入图表
            insertImgsheet(wwb, vecImg);
            //写入Excel对象
            wwb.write();
            wwb.close();
        } catch (Exception e)
        {
            YTLogger.logDebug(e);
        } finally
        {
            // 操作完成时，关闭对象，释放占用的内存空间
            workbook.close();
        }
    }
    
    /**
     * 插入数据
     * @param wwb WritableWorkbook : 工作簿
     * @param dataSheet WritableSheet : 工作表
     * @throws RowsExceededException
     * @throws WriteException
     */
    private void insertData(WritableWorkbook wwb, WritableSheet dataSheet, Vector vecData) throws RowsExceededException, WriteException
    {
        // 获得标题单元格对象        
        modiStrCell(dataSheet, 2, 0, &quot;工商银行江苏省分行 个人网上银行业务种类/开销户明细报表（2005-12）&quot;, null);
        // 修改数据单元格数据
        for(int i = 0; i &lt; vecData.size(); i ++)
        {
            VireObj obj = (VireObj)vecData.get(i);
            modiStrCell(dataSheet, 0, TITLE_LENGTH + i, obj.getOrgNo(), null);
            modiStrCell(dataSheet, 1, TITLE_LENGTH + i, obj.getOrgName(), null);
            modiNumCell(dataSheet, 2, TITLE_LENGTH + i, obj.getOpenAcc(), null);
            modiNumCell(dataSheet, 3, TITLE_LENGTH + i, obj.getDestoryAcc(), null);
            modiNumCell(dataSheet, 4, TITLE_LENGTH + i, obj.getTotalAcc(), null);
            modiNumCell(dataSheet, 5, TITLE_LENGTH + i, obj.getMonthInCount(), null);
            modiNumCell(dataSheet, 6, TITLE_LENGTH + i, obj.getTotalInMoney(), null);
            modiNumCell(dataSheet, 7, TITLE_LENGTH + i, obj.getMonthOutCount(), null);
            modiNumCell(dataSheet, 8, TITLE_LENGTH + i, obj.getMonthOutMoney(), null);
        }    
        // 删除空行
        for (int j = vecData.size() + TITLE_LENGTH; j &lt; SHEET_HEIGHT; j++)
        {
            dataSheet.removeRow(vecData.size() + TITLE_LENGTH);
        }        
        // 插入公式
        for(int i = 2; i &lt; SHEET_WIDTH; i ++)
        {
            modiFormulaCell(dataSheet, i, vecData.size() + TITLE_LENGTH, 8, vecData.size() + TITLE_LENGTH, null);
        }        
    }

    /**
     * 修改字符单元格的值
     * @param dataSheet WritableSheet : 工作表
     * @param col int : 列
     * @param row int : 行
     * @param str String : 字符
     * @param format CellFormat : 单元格的样式
     * @throws RowsExceededException
     * @throws WriteException
     */
    private void modiStrCell(WritableSheet dataSheet, int col, int row, String str, CellFormat format) throws RowsExceededException, WriteException
    {
        // 获得单元格对象
        WritableCell cell = dataSheet.getWritableCell(col, row);
        // 判断单元格的类型, 做出相应的转化
        if (cell.getType() == CellType.EMPTY)
        {
            Label lbl = new Label(col, row, str);
            if(null != format)
            {
                lbl.setCellFormat(format);
            } else
            {
                lbl.setCellFormat(cell.getCellFormat());
            }
            dataSheet.addCell(lbl);
        } else if (cell.getType() == CellType.LABEL)
        {
            Label lbl = (Label)cell;
            lbl.setString(str);
        } else if (cell.getType() == CellType.NUMBER)
        {
            // 数字单元格修改
            Number n1 = (Number)cell;
            n1.setValue(42.05);
        }
    }
    
    /**
     * 修改数字单元格的值
     * @param dataSheet WritableSheet : 工作表
     * @param col int : 列
     * @param row int : 行
     * @param num double : 数值
     * @param format CellFormat : 单元格的样式
     * @throws RowsExceededException
     * @throws WriteException
     */
    private void modiNumCell(WritableSheet dataSheet, int col, int row, double num, CellFormat format) throws RowsExceededException, WriteException
    {
        // 获得单元格对象
        WritableCell cell = dataSheet.getWritableCell(col, row);
        // 判断单元格的类型, 做出相应的转化
        if (cell.getType() == CellType.EMPTY)
        {
            Number lbl = new Number(col, row, num);
            if(null != format)
            {
                lbl.setCellFormat(format);
            } else
            {
                lbl.setCellFormat(cell.getCellFormat());
            }
            dataSheet.addCell(lbl);
        } else if (cell.getType() == CellType.NUMBER)
        {
            // 数字单元格修改
            Number lbl = (Number)cell;
            lbl.setValue(num);
        } else if (cell.getType() == CellType.LABEL)
        {
            Label lbl = (Label)cell;
            lbl.setString(String.valueOf(num));
        }
    }
    
    /**
     * 修改公式单元格的值
     * @param dataSheet WritableSheet : 工作表
     * @param col int : 列
     * @param row int : 行
     * @param startPos int : 开始位置
     * @param endPos int : 结束位置
     * @param format
     * @throws RowsExceededException
     * @throws WriteException
     */
    private void modiFormulaCell(WritableSheet dataSheet, int col, int row, int startPos, int endPos, CellFormat format) throws RowsExceededException, WriteException
    {
        String f = getFormula(col, row, startPos, endPos);
        // 插入公式（只支持插入，不支持修改）
        WritableCell cell = dataSheet.getWritableCell(col, row);
        if (cell.getType() == CellType.EMPTY)
        {                    
            // 公式单元格
            Formula lbl = new Formula(col, row, f);
            if(null != format)
            {
                lbl.setCellFormat(format);
            } else
            {
                lbl.setCellFormat(cell.getCellFormat());
            }
            dataSheet.addCell(lbl);
        } else if (cell.getType() == CellType.STRING_FORMULA)
        {
            YTLogger.logWarn(&quot;Formula modify not supported!&quot;);
        }
    }
    
    /**
     * 得到公式
     * @param col int : 列
     * @param row int : 行
     * @param startPos int : 开始位置
     * @param endPos int : 结束位置
     * @return String
     * @throws RowsExceededException
     * @throws WriteException
     */
    private String getFormula(int col, int row, int startPos, int endPos)
            throws RowsExceededException, WriteException
    {
        char base = 'A';
        char c1 = base;
        StringBuffer formula = new StringBuffer(128);
        // 组装公式
        formula.append(&quot;SUM(&quot;);
        if (col &lt;= 25)
        {
            c1 = (char) (col % 26 + base);
            formula.append(c1).append(startPos).append(&quot;:&quot;)
                   .append(c1).append(endPos).append(&quot;)&quot;);
        } else if (col &gt; 25)
        {
            char c2 = (char) ((col - 26) / 26 + base);
            c1 = (char) ((col - 26) % 26 + base);
            formula.append(c2).append(c1).append(startPos).append(&quot;:&quot;)
                   .append(c2).append(c1).append(endPos).append(&quot;)&quot;);
        }

        return formula.toString();
    }
    
    /**
     * 插入图表工作表
     * @param wwb WritableWorkbook : 工作簿
     * @param vecImg Vector : 图像链表
     * @throws RowsExceededException
     * @throws WriteException
     */
    private void insertImgsheet(WritableWorkbook wwb, Vector vecImg)
            throws RowsExceededException, WriteException
    {
        // 插入图像
        WritableSheet imgSheet;
        if((wwb.getSheets()).length &lt; 2)
        {
            imgSheet = wwb.createSheet(&quot;图表&quot;, 1);
        } else
        {
            imgSheet = wwb.getSheet(1);
        }
        
        for (int i = 0; i &lt; vecImg.size(); i++)
        {
            ChartImg chart = (ChartImg) vecImg.get(i);
            // 插入图像标题
            Label lbl = new Label(0, 2 + 20 * i, chart.getImgTitle());
            WritableFont font = new WritableFont(WritableFont.ARIAL,
                    WritableFont.DEFAULT_POINT_SIZE, WritableFont.NO_BOLD, false,
                    UnderlineStyle.NO_UNDERLINE, Colour.DARK_BLUE2);
            WritableCellFormat background = new WritableCellFormat(font);
            background.setWrap(true);
            background.setBackground(Colour.GRAY_25);
            imgSheet.mergeCells(0, 2 + 20 * i, 9, 2 + 20 * i);
            lbl.setCellFormat(background);
            imgSheet.addCell(lbl);
            // 插入图像单元格
            insertImgCell(imgSheet, 2, 4 + 20 * i, 8, 15, chart.getImgName());
        }
    }

    /**
     * 插入图像到单元格（图像格式只支持png）
     * @param dataSheet WritableSheet : 工作表
     * @param col int : 列
     * @param row int : 行
     * @param width int : 宽
     * @param height int : 高
     * @param imgName String : 图像的全路径
     * @throws RowsExceededException
     * @throws WriteException
     */
    private void insertImgCell(WritableSheet dataSheet, int col, int row, int width,
            int height, String imgName) throws RowsExceededException, WriteException
    {
        File imgFile = new File(imgName);
        WritableImage img = new WritableImage(col, row, width, height, imgFile);
        dataSheet.addImage(img);
    }
    
    /**
     * 测试
     * @param args
     */
    public static void main(String[] args)
    {
        XLSDemo demo = new XLSDemo();
        demo.makeXls();
    }
}</pre>
&nbsp;
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/227084#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Aug 2008 16:54:02 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/227084</link>
        <guid>http://dmewy.javaeye.com/blog/227084</guid>
      </item>
      <item>
        <title>PropertyPlaceholderConfigurer用法</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/218463" style="color:red;">http://dmewy.javaeye.com/blog/218463</a>&nbsp;
          发表时间: 2008年07月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: medium"><br /><br />Spring的框架中为您提供了一个 BeanFactoryPostProcessor 的实作类别： org.springframework.beans.factory.config.PropertyPlaceholderConfigurer。藉由这个类别，您可以将一些组态设定，移出至.properties档案中，如此的安排可以让XML定义档负责系统相关设定，而.properties档可以作为客户根据需求，自定义一些相关的参数。<br /><br />来看一个Bean定义档的实际例子：<br /><br />    * beans-config.xml<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?> <br />&lt;!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" <br />  "http://www.springframework.org/dtd/spring-beans.dtd"> <br /><br />&lt;beans>  <br />    &lt;bean id="configBean" <br /> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <br />        &lt;property name="location"> <br />            &lt;value>hello.properties&lt;/value> <br />        &lt;/property> <br />    &lt;/bean> <br /><br />    &lt;bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> <br />        &lt;property name="helloWord"> <br />            &lt;value>${onlyfun.caterpillar.helloWord}&lt;/value> <br />        &lt;/property> <br />    &lt;/bean><br />&lt;/beans><br /><br /><br />假设在helloBean中有许多依赖注入的属性，这些都是比较不常变动的属性，而其中helloWord会经常变动，可以透过hello.properties来简单的设定，而这个资讯已设定在configBean的location属性中：<br /><br />    * hello.properties<br /><br />onlyfun.caterpillar.helloWord=Welcome!<br /><br /><br />在helloBean的helloWord属性中，${onlyfun.caterpillar.helloWord}将会被hello.properties的helloWord所取代。<br /><br />如果有多个.properties档案，则可以透过locations属性来设定，例如：<br /><br />    * beans-config.xml<br /><br /> <br /><br />&lt;?xml version="1.0" encoding="UTF-8"?> <br />&lt;!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" <br />  "http://www.springframework.org/dtd/spring-beans.dtd"> <br /><br />&lt;beans>  <br />    &lt;bean id="configBean" <br />  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <br />        &lt;property name="locations"> <br />            &lt;list><br />                &lt;value>hello.properties&lt;/value> <br />                &lt;value>welcome.properties&lt;/value> <br />                &lt;value>other.properties&lt;/value> <br />    <br />            &lt;/list><br />        &lt;/property>     <br />    &lt;/bean> <br /><br />    &lt;bean id="helloBean" class="onlyfun.caterpillar.HelloBean"> <br />        &lt;property name="helloWord"> <br />            &lt;value>${onlyfun.caterpillar.helloWord}&lt;/value> <br />        &lt;/property> <br />        ...<br />    &lt;/bean><br />&lt;/beans><br /><br /></span>
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/218463#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 23 Jul 2008 09:31:05 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/218463</link>
        <guid>http://dmewy.javaeye.com/blog/218463</guid>
      </item>
      <item>
        <title>近期学到的小技巧.</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/215516" style="color:red;">http://dmewy.javaeye.com/blog/215516</a>&nbsp;
          发表时间: 2008年07月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>iframe:</p>
<p>&nbsp;</p>
<p>父页面调用ifream的方法: &nbsp; document.frames( &quot;iframename &quot;).functionName(); <br />
 iframe调用父页的方法：parent.functionName();</p>
<p>父窗体改变iframe的src.&nbsp; getElementsByName(&quot;iframename&quot;).src=&quot;xxxx&quot;;</p>
<p>&nbsp;</p>
<p>以&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;</p>
<p>打开的新窗体可以使用window.opener.XX来调用..</p>
<p>&nbsp;</p>
<p>APP server:</p>
<p>使用websphere开发时.如果不能提交中文.请修改目录中encoding.properties //zh=UTF-8 默认GB2312</p>
<p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://dmewy.javaeye.com/blog/215516#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Jul 2008 17:58:40 +0800</pubDate>
        <link>http://dmewy.javaeye.com/blog/215516</link>
        <guid>http://dmewy.javaeye.com/blog/215516</guid>
      </item>
      <item>
        <title>DisplayTag标签应用</title>
        <author>dmewy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://dmewy.javaeye.com">dmewy</a>&nbsp;
          链接：<a href="http://dmewy.javaeye.com/blog/208099" style="color:red;">http://dmewy.javaeye.com/blog/208099</a>&nbsp;
          发表时间: 2008年06月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;DisplayTag是一个非常好用的表格显示标签，适合MVC模式，其主页在<a href="http://displaytag.sourceforge.net/">http://displaytag.sourceforge.net</a>
&nbsp; <br />
<strong>一、最简单的情况，未使用&lt;display:column/&gt;标签<br />
</strong>
&nbsp; &lt;%request.setAttribute( &quot;test&quot;, new ReportList(6) );%&gt;<br />
&nbsp; &lt;display:table name=&quot;test&quot; /&gt;<br />
&nbsp; 标签遍历List里的每一个对象，并将对象里的所有属性显示出来。一般用于开发的时候检查对象数据的完整性。<br />
&nbsp; <br />
<strong>二、使用&lt;display:column/&gt;标签的情况</strong>
<br />
&lt;display:table name=&quot;test&quot;&gt;<br />
&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;name&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;status&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;description&quot; title=&quot;Comments&quot;/&gt;<br />
&lt;/display:table&gt;<br />
&nbsp;&nbsp; property对应List里对象的属性（用getXXX()方法取得），title则对应表格表头里的列名。定义列有两种方式：<br />
&nbsp;&nbsp; A、&lt;display:column property=&quot;email&quot; /&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用&lt;display:column/&gt;标签里的property属性来定义<br />
&nbsp;&nbsp; B、&lt;display:column title=&quot;email&quot;&gt;email@it.com&lt;/display:column&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在&lt;display:column/&gt;标签体里增加内容，可以是常量，也可以用其他标签等等<br />
&nbsp;&nbsp; 两种方式比较，用property属性来定义更加快速和利于排序。<br />
&nbsp;&nbsp; <br />
<strong>三、表格显示样式的定义<br />
</strong>
&nbsp; A、在&lt;display:table/&gt;和&lt;display:column/&gt;标签里指定标准的html属性，烦琐<br />
&nbsp; B、修改样式表<br />
&lt;display:table name=&quot;test&quot; class=&quot;mars&quot;&gt;<br />
&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; class=&quot;idcol&quot;/&gt;<br />
&nbsp; &lt;display:column property=&quot;name&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;status&quot; class=&quot;tableCellError&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;description&quot; title=&quot;Comments&quot;/&gt;<br />
&lt;/display:table&gt;<br />
&nbsp;&nbsp; 通过class属性来指定所要应用的样式。可以在其默认样式表里（./css/screen.css）直接修改<br />
&nbsp;&nbsp; <br />
<strong>四、标签取得数据的数据源<br />
</strong>
&nbsp; 有四种范围<br />
&nbsp;&nbsp; pageScope <br />
&nbsp;&nbsp; requestScope (默认)&nbsp; &lt;display:table name=&quot;test2&quot; &gt;<br />
&nbsp;&nbsp; sessionScope&nbsp; &lt;display:table name=&quot;sessionScope.holder.list&quot; &gt; 注意，这里要指定范围，非默认<br />
&nbsp;&nbsp; applicationScope <br />
&nbsp;&nbsp; <br />
<strong>五、通过增加id属性创建隐含的对象<br />
</strong>
&lt;display:table name=&quot;test&quot; id=&quot;testit&quot;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;name&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;display:column title=&quot;static value&quot;&gt;static&lt;/display:column&gt;<br />
&nbsp;&nbsp;&nbsp;
&lt;display:column title=&quot;row number
(testit_rowNum)&quot;&gt;&lt;%=pageContext.getAttribute(&quot;testit_rowNum&quot;)%&gt;&lt;/display:column&gt;<br />
&nbsp;&nbsp;&nbsp;
&lt;display:column
title=&quot;((ListObject)testit).getMoney()&quot;&gt;&lt;%=((ListObject)pageContext.getAttribute(&quot;testit&quot;)).getMoney()%&gt;&lt;/display:column&gt;<br />
&lt;/display:table&gt;<br />
&nbsp;&nbsp; 注意到在&lt;display:table/&gt;里增加了id属性，这时就在page context里创建了一个隐含对象，指向List里的当前对象，<br />
&nbsp;&nbsp; 可以通过(ListObject)pageContext.getAttribute(&quot;id&quot;)来捕获这个对象。同时还创建了一个id_rowNum对象，同样，可<br />
&nbsp;&nbsp; 通过pageContext.getAttribute(&quot;testit_rowNum&quot;)来捕获，它仅仅代表当前行的行数。<br />
&nbsp;&nbsp; 有了这两个隐含对象，就可以通过其他标签来访问，例如Jstl:<br />
&nbsp; &lt;display:table id=&quot;row&quot; name=&quot;mylist&quot;&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;display:column title=&quot;row number&quot; &gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;c:out value=&quot;${row_rowNum}&quot;/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/display:column&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;display:column title=&quot;name&quot; &gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;c:out value=&quot;${row.first_name}&quot;/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;c:out value=&quot;${row.last_name}&quot;/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/display:column&gt;<br />
&nbsp; &lt;/display:table&gt;<br />
&nbsp; <br />
<strong>六、显示部分数据</strong>
<br />
&nbsp;&nbsp; 显示开始五条数据：通过设定length属性<br />
&lt;display:table name=&quot;test&quot; length=&quot;5&quot;&gt;<br />
&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;status&quot; /&gt;<br />
&lt;/display:table&gt;<br />
&nbsp;&nbsp; 显示第三到第八条数据：通过设定offset和length属性<br />
&lt;display:table name=&quot;test&quot; offset=&quot;3&quot; length=&quot;5&quot;&gt;<br />
&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;status&quot; /&gt;<br />
&lt;/display:table&gt;&nbsp; 
</p>
<p><strong>七、对email和url地址的直接连接</strong>
<br />
&nbsp;&lt;display:table name=&quot;test&quot; &gt;<br />
&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; autolink=&quot;true&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;url&quot; autolink=&quot;true&quot; /&gt;<br />
&nbsp;&lt;/display:table&gt;<br />
&nbsp;如果要显示的对象里包含email和url地址，则可以在display:column里直接设定autolink=&quot;true&quot;来直接连接<br />
&nbsp;<br />
<strong>八、使用装饰模式转换数据显示（写自己的 decorator ）</strong>
<br />
&nbsp; A、对整个表格应用decorator<br />
&nbsp; &lt;display:table name=&quot;test&quot; decorator=&quot;org.displaytag.sample.Wrapper&quot; &gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;status&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;date&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;money&quot; /&gt;<br />
&nbsp; &lt;/display:table&gt;<br />
&nbsp;&nbsp;&nbsp; org.displaytag.sample.Wrapper即自己写的decorator，它要继承TableDecorator类，看看它的一个方法：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getMoney()<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.moneyFormat.format(((ListObject) this.getCurrentRowObject()).getMoney());<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; 很明显，它通过父类的getCurrentRowObject()方法获得当前对象，然后对其getMoney()方法进行&lsquo;油漆&rsquo;<br />
&nbsp; B、对单独的column应用decorator<br />
&nbsp; &lt;display:table name=&quot;test&quot;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;status&quot; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;display:column property=&quot;date&quot; decorator=&quot;org.displaytag.sample.LongDateWrapper&quot; /&gt;<br />
&nbsp; &lt;/display:table&gt;<br />
&nbsp;&nbsp;&nbsp; org.displaytag.sample.LongDateWrapper要实现ColumnDecorator接口，它的方法：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public final String decorate(Object columnValue)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date = (Date) columnValue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.dateFormat.format(date);<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; 显然，它获得不了当前对象（因为它实现的是接口），仅仅是获得该对象的columnValue，然后&lsquo;油漆&rsquo;<br />
&nbsp;&nbsp;&nbsp; <br />
<strong>九、创建动态连接<br />
</strong>
&nbsp;&nbsp; 有两种方法创建动态连接：<br />
&nbsp;&nbsp; A、在&lt;display:column/&gt;里通过增加href、paramId、paramName、paramScope、paramProperty属性<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; href&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基本的URL 地址<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paramId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 加在URL 地址后的参数名称<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paramName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据bean的名称，一般为null（即使用当前List里的对象）<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paramScope&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据bean的范围，一般为null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paramProperty&nbsp;&nbsp;&nbsp; 数据bean的属性名称，用来填充URL 地址后的参数值<br />
&lt;display:table name=&quot;sessionScope.details&quot;&gt;<br />
&nbsp; &lt;display:column property=&quot;id&quot; title=&quot;ID&quot; href=&quot;details.jsp&quot; paramId=&quot;id&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; href=&quot;details.jsp&quot; paramId=&quot;action&quot; paramName=&quot;testparam&quot; paramScope=&quot;request&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;status&quot; href=&quot;details.jsp&quot; paramId=&quot;id&quot; paramProperty=&quot;id&quot; /&gt;<br />
&lt;/display:table&gt;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 这种方法简便直接，但缺点是无法产生类似details.jsp?id=xx&amp;action=xx的复合URL<br />
&nbsp;&nbsp; B、应用decorator 创建动态连接：<br />
&lt;display:table name=&quot;sessionScope.details&quot; decorator=&quot;org.displaytag.sample.Wrapper&quot; &gt;<br />
&nbsp; &lt;display:column property=&quot;link1&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp; &lt;display:column property=&quot;link2&quot; title=&quot;Actions&quot; /&gt;<br />
&lt;/display:table&gt;<br />
&nbsp;&nbsp; org.displaytag.sample.Wrapper里的方法：<br />
&nbsp;public String getLink1()<br />
&nbsp;{<br />
&nbsp;&nbsp;ListObject lObject= (ListObject)getCurrentRowObject();<br />
&nbsp;&nbsp;int lIndex= getListIndex();<br />
&nbsp;&nbsp;return &quot;&lt;a href=\&quot;details.jsp?index=&quot; + lIndex + &quot;\&quot;&gt;&quot; + lObject.getId() + &quot;&lt;/a&gt;&quot;;<br />
&nbsp;}</p>
<p><br />
&nbsp;public String getLink2()<br />
&nbsp;{<br />
&nbsp;&nbsp;ListObject lObject= (ListObject)getCurrentRowObject();<br />
&nbsp;&nbsp;int lId= lObject.getId();</p>
<p>&nbsp;&nbsp;return &quot;&lt;a href=\&quot;details.jsp?id=&quot; + lId<br />
&nbsp;&nbsp;&nbsp;+ &quot;&amp;action=view\&quot;&gt;View&lt;/a&gt; | &quot;<br />
&nbsp;&nbsp;&nbsp;+ &quot;&lt;a href=\&quot;details.jsp?id=&quot; + lId<br />
&nbsp;&nbsp;&nbsp;+ &quot;&amp;action=edit\&quot;&gt;Edit&lt;/a&gt; | &quot;<br />
&nbsp;&nbsp;&nbsp;+ &quot;&lt;a href=\&quot;details.jsp?id=&quot; + lId<br />
&nbsp;&nbsp;&nbsp;+ &quot;&amp;action=delete\&quot;&gt;Delete&lt;/a&gt;&quot;;<br />
&nbsp;}</p>
<p><strong>十、分页<br />
</strong>
&nbsp;&nbsp; 实现分页非常的简单，增加一个pagesize属性指定一次想显示的行数即可<br />
&lt;display:table name=&quot;sessionScope.test&quot; pagesize=&quot;10&quot;&gt;<br />
&nbsp;&lt;display:column property=&quot;id&quot; title=&quot;ID&quot; /&gt;<br />
&nbsp;&lt;display:column property=&quot;name&quot; /&gt;<br />
&nbsp;&lt;display:column property=&quot;email&quot; /&gt;<br />
&nbsp;&lt;display:column property=&quot;status&quot; /&gt;<br />
&lt;/display:table&gt;</p>
<p><strong>十一、排序<br />
</strong>
&nbsp;&nbsp; 排序实现也是很简单，在需要排序的column里增加sortable=&quot;true&quot;属性，headerClass=&quot;sortable&quot;仅仅是<br />
&nbsp;&nbsp; 指定显示的样式。column里的属性对象要实现Comparable接口，如果没有