导入导出excel文件



场景描述

将数据库表中的数据按照定义的EXCEL模板进行导出,下载到本地;
将EXCEL中的数据导入数据库相应的表中。

场景目标

通过本场景,解决EXCEL的导入导出问题,供项目中学习使用。

页面效果

点击<导出员工信息>按钮,生成员工信息的excel文件。
选择一个excel文件,点击<导入员工信息>按钮,则把excel数据导入数据库表。

注意
导入文件的内容数据格式如下,第一行指定字段名,需要用字段#开始,第二行是中文字段标识,第三行以后才是数据。例如:
#empid#orgid#empcode#empname#sex#birthday#postcode#address#phone#wage
员工id机构代码员工代码姓名性别生日邮编地址电话薪资
212张无忌M1972-11-30710071上海张江高科技园区碧波路456号4层800800022000
313张小宝M1974-5-19710072北京市海淀区彩和坊路8号天创科技大厦东门1301室800800032000
414赵大海M1977-7-8710073广州市天河区体育东路800800042000


开发步骤

步骤1:创建构件包com.primeton.example.excel。

步骤2:数据建模
根据附件提供的sql脚本建表,新建数据集sampledataset.dataset并将表sampledataset导成数据实体ExampleEmp。

步骤3:运算逻辑和class开发

  • com.primeton.example.excel.ChangeUtil:
    
    package com.primeton.example.excel;
    import java.math.BigDecimal;
    import java.sql.Timestamp;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Enumeration;
    import java.util.StringTokenizer;
    import java.util.Vector;
    
    /**
     *
     * 转换工具类
     *
     * @author primeton
     * wengzr (mailto:)
     */
     
    public class ChangeUtil {
     /**
      * 时间格式(年月日)
      */
     public static final String DATE_FORMAT_YMD = "yyyyMMdd";
     /**
      * 时间格式(年月)
      */
     public static final String DATE_FORMAT_YM = "yyyyMM";
     /**
      * 时间格式(年)
      */
     public static final String DATE_FORMAT_Y = "yyyy";
     
     public static final String DATE_FORMAT_YMD_HMS="yyyy-MM-dd HH:mm:ss";
     
     /**
      * ChangeUtil类的缺省构造器。
      */
     private ChangeUtil() {
     }
     
     /**
      * 将一个以','分割的字符串,转换为一个Vector对象。这是changeStringToVector(String str, String token)的简化版本。
      *
      * @param _str 需要转换的字符串
      * @return 包含了字符串中元素的Vector对象。
      * @see #changeStringToVector
      */
     public static Vector changeStringToVector(String _str){
      return changeStringToVector(_str, ",");
     }
     /**
      * 将一个以字符串token分割的字符串,转换为一个Vector对象。如"姓名[token]年龄"被转换为一个Vector,该Vector包含两个元素,第一个是"姓名",第二个是"年龄"。
      *
      * @param _str 需要转换的字符串
      * @param _token 字符串中分割的token。如空格" ",或":"等。
      * @return 包含了字符串中元素的Vector对象。
      */
     public static Vector changeStringToVector(String _str, String _token) {
      if( _str== null) {
       return null;
      }
      
      Vector<String> temp = new Vector<String>();
      StringTokenizer st = new StringTokenizer(_str, _token);
      while (st.hasMoreTokens()) {
       temp.add(st.nextToken());
      }
      return temp;
     }
     /**
      * 将一个Vector对象中保存的字符串元素使用","分隔符转换为一个字符串,这是public static Vector changeStringToVector(String str)的逆操作。
      *
      * @param _v 包含了字符串数据元素的Vector对象
      * @return 一个以","为分隔符的字符串
         */
     public static String changeVectorToString(Vector _v) {
      return changeVectorToString(_v, ",");
     }
     /**
      * 将一个Vector对象中保存的字符串元素使用token分隔符转换为一个字符串,
      * 这是public static Vector changeStringToVector(String str, String token)的逆操作。
      * @param _v 包含了字符串数据元素的Vector对象
      * @param _token 字符串中分割的token。如空格" ",或":"等。
      * @return 一个以token为分隔符的字符串
      */
     public static String changeVectorToString(Vector _v, String _token) {
      if( _v == null) {
       return null;
      }
      Enumeration enumeration = _v.elements();
      String str = "";
      while (enumeration.hasMoreElements()) {
       str = str + (String) (enumeration.nextElement()) + _token;
      }
      str = str.substring(0, str.length() - 1);
      return str;
     }
     /**
      * 将一个字符串数组中保存的字符串元素使用","分隔符转换为一个字符串。
      *
      * @param _strArray 包含了字符串数据元素的字符串数组
      * @return 一个以","为分隔符的字符串
      * @see #changeArrayToString
      */
     public static String changeArrayToString(String[] _strArray) {
      return changeArrayToString(_strArray, ",");
     }
     /**
      * 将一个字符串数组中保存的字符串元素使用token分隔符转换为一个字符串,
      * 这是public static Vector changeStringToVector(String str, String token)的逆操作。
      * @param _strArray 包含了字符串数据元素的字符串数组
      * @param _token 分隔字符串使用的分隔符。
      * @return 一个以token为分隔符的字符串
      */
     public static String changeArrayToString(String[] _strArray,String _token) {
      if( _strArray == null) {
       return null;
      }
      int size = _strArray.length;
      if (size == 0) {
       return null;
      } else if (size == 1) {
       return _strArray[0];
      } else {
       String temp = _strArray[0];
       for (int i = 1; i < size; i++) {
        temp = temp + _token + _strArray[i];
       }
       return temp;
      }
     }
     /**
      * 将一个使用","分隔符分隔的字符串,转变为一个字符串数组。
      *
      * @param _str 用token分隔符分隔的字符串
      * @return 字符串数组
      */
     public static String[] changeStringToArray(String _str) {
      return changeStringToArray(_str, ",");
     }
     /**
      * 将一个使用token分隔符分隔的字符串,转变为一个字符串数组。
      *
      * @param _str 用token分隔符分隔的字符串
      * @param _token 字符串的分隔符
      * @return 字符串数组
      */
     public static String[] changeStringToArray(String _str, String _token) {
      if( _str ==null) {
       return null;
      }
      Vector v = changeStringToVector(_str, _token);
      String[] strArray = new String[v.size()];
      int i = 0;
      for (Enumeration em = v.elements(); em.hasMoreElements(); i++) {
       strArray[i] = (String) em.nextElement();
      }
      return strArray;
     }
     /**
      * 获得以参数_fromDate为基数的年龄
      *
      * @param _birthday 生日
      * @param _fromDate 起算时间
      * @return 年龄(起算年-出生年)
      */
     public static int getAgeFromBirthday(java.util.Date _birthday,java.util.Date _fromDate) {
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_birthday);
      int birthdayYear = calendar.get(Calendar.YEAR);
      int birthdayMonth = calendar.get(Calendar.MONTH);
      int birthdayDay = calendar.get(Calendar.DAY_OF_MONTH);
      calendar.clear();
      calendar.setTime(_fromDate);
      int currentYear = calendar.get(Calendar.YEAR);
      int currentMonth = calendar.get(Calendar.MONTH);
      int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
      calendar.clear();
      int age = currentYear - birthdayYear;
      if (!((currentMonth >= birthdayMonth)&& (currentDay >= birthdayDay))) {
       age--;
      }
      return age;
     }
     /**
      * 获得当前年龄
      *
      * @param _birthday 生日
      * @return 年龄(起算年-出生年)
      */
     public static int getAgeFromBirthday(java.util.Date _birthday) {
      return getAgeFromBirthday(_birthday,new java.util.Date(System.currentTimeMillis()));
     }
     /**
      * 获得当前年龄
      *
      * @param _birthday 生日
      * @return 年龄(起算年-出生年)
      */
     public static int getAgeFromBirthday(java.sql.Timestamp _birthday) {
      return getAgeFromBirthday(new java.util.Date(_birthday.getTime()),new java.util.Date(System.currentTimeMillis()));
     }
     /**
      * 使用格式{@link #DATE_FORMAT_YMD}格式化日期输出
      *
      * @param _date 日期对象
      * @return 格式化后的日期
      */
     public static String formatDate(java.util.Date _date) {
      return formatDate(_date, DATE_FORMAT_YMD);
     }
     /**
      * 使用格式<b>_pattern</b>格式化日期输出
      *
      * @param _date 日期对象
      * @param _pattern 日期格式
      * @return 格式化后的日期
      */
     public static String formatDate(java.util.Date _date, String _pattern) {
      if( _date == null) {
       return null;
      }
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat(_pattern);
      String stringDate = simpleDateFormat.format(_date);
      return stringDate;
     }
     /**
      * 使用中文字符以简单的形式("年 月 日")格式化时间串
      *
      * @param _date 日期对象
      * @return 格式化后的日期
      */
     public static String simplefFormatChineseDate(java.util.Date _date) {
      if( _date == null) {
       return null;
      }
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      StringBuffer sb = new StringBuffer();
      sb.append(calendar.get(Calendar.YEAR))
       .append("年")
       .append(calendar.get(Calendar.MONTH) + 1)
       .append("月")
       .append(Calendar.DAY_OF_MONTH)
       .append("日");
      calendar.clear();
      return sb.toString();
     }
     /**
      * 使用中文字符以复杂的形式("年 月 日 上午 时 分 秒")格式化时间串
      *
      * @param _date 日期对象
      * @return 格式化后的日期
      */
     public static String complexFormatChineseDate(java.util.Date _date) {
      if( _date == null) {
       return null;
      }
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      StringBuffer sb = new StringBuffer();
      sb.append(calendar.get(Calendar.YEAR))
       .append("年")
       .append(calendar.get(Calendar.MONTH) + 1)
       .append("月")
       .append(Calendar.DAY_OF_MONTH)
       .append("日")
       .append(Calendar.HOUR_OF_DAY)
       .append("时")
       .append(Calendar.MINUTE)
       .append("分")
       .append(Calendar.SECOND)
       .append("秒");
      calendar.clear();
      return sb.toString();
     }
     /**
      * 将时间串转变为时间对象,输入参数<b>_dateStr</b>必须遵循格式{@link #DATE_FORMAT_YMD}
      *
      * @param _dateStr 时间串
      * @return 时间对象
      */
     public static java.util.Date changeToDate(String _dateStr) throws IllegalArgumentException{
      return changeToDate(_dateStr, DATE_FORMAT_YMD);
     }
     /**
      * 将时间串转变为时间对象
      *
      * @param _dateStr 时间串
      * @param _pattern 时间串使用的模式
      * @return 时间对象
      * @throws ParamValidateException 当输入的时间串和它使用的模式不匹配时掷出
      */
     public static java.util.Date changeToDate(String _dateStr,String _pattern) throws IllegalArgumentException  {
      if (_dateStr == null || _dateStr.trim().equals("")) {
       return null;
      }
      java.util.Date date = null;
      SimpleDateFormat format = new SimpleDateFormat(_pattern);
      try {
       date = format.parse(_dateStr);
      } catch (java.text.ParseException pe) {
       throw new IllegalArgumentException("不能使用模式:[" + _pattern + "]格式化时间串:[" + _dateStr + "]");
      }
      return date;
     }
     /**
      * 将时间串转变为数据库时间对象,输入参数<b>_dateStr</b>必须遵循格式{@link #DATE_FORMAT_YMD}
      *
      * @param _dateStr 时间串
      * @return 数据库时间对象
      */
     public static java.sql.Date changeToDBDate(String _dateStr) throws IllegalArgumentException{
      return changeForDBDate(changeToDate(_dateStr, DATE_FORMAT_YMD));
     }
     /**
      * 将时间串转变为数据库时间对象
      *
      * @param _dateStr 时间串
      * @param _pattern 时间串使用的模式
      * @return 时间对象
      * @throws ParamValidateException 当输入的时间串和它使用的模式不匹配时掷出
      */
     public static java.sql.Date changeToDBDate(String _dateStr,String _pattern) throws IllegalArgumentException {
      return changeForDBDate(changeToDate(_dateStr, _pattern));
     }
     /**
      * 将java.util.Date对象转换为java.sql.Date对象
      *
      * @param _date 待转化的java.util.Date 对象
      * @return java.sql.Date对象
      */
     public static java.sql.Date changeForDBDate(java.util.Date _date) {
      if (_date == null) {
       return null;
      }
      return new java.sql.Date(_date.getTime());
     }
     /**
      * 将java.sql.Date对象转换为java.util.Date对象
      *
      * @param _date 待转化的java.sql.Date对象
      * @return java.util.Date对象
      */
     public static java.util.Date changFromDBDate(java.sql.Date _date) {
      return (java.util.Date) _date;
     }
     /**
      * 将java.util.Date对象转换为java.sql.Timestamp对象
      *
      * @param _date 待转化的java.util.Date 对象
      * @return java.sql.Timestamp对象
      */
     public static java.sql.Timestamp changeToTimestamp(java.util.Date _date) {
      if (_date == null) {
       return null;
      }
      return new java.sql.Timestamp(_date.getTime());
     }
     /**
      * 将java.sql.Timestamp对象转换为java.util.Date对象
      *
      * @param _date 待转化的java.sql.Timestamp 对象
      * @return java.util.Date 对象
      */
     public static java.util.Date changeFromTimestamp(java.sql.Timestamp _date) {
      return (java.util.Date) _date;
     }
     /**
      * 改变字符串的编码方式(ISO8859_1)为(GBK),以支持中文
      *
      * @param _str 待转变的字符串
      * @return 采用GBK编码的字符串
      */
     public static String changeToGB(String _str) throws Exception{
      if( _str == null) {
       return null;
      }
      String gbStr = null;
      try {
       gbStr = new String(_str.getBytes("ISO8859_1"), "GBK");
      } catch (Exception e) {
       throw e;
      }
      return gbStr;
     }
     /**
      * 改变字符串的编码方式(GBK)为(ISO8859_1)
      *
      * @param _str 待转变的字符串
      * @return 采用ISO8859_1编码的字符串
      */
     public static String changeFromGB(String _str)throws Exception {
      if( _str == null) {
       return null;
      }
      String isoStr = null;
      try {
       isoStr = new String(_str.getBytes("GBK"), "ISO8859_1");
      } catch (Exception e) {
       throw e;
      }
      return isoStr;
     }
     /**
      * 获得日期的年
      *
      * @param _date 日期对象
      * @return 日期的年
      */
     public static int getYear(java.util.Date _date) {
      
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      int year = calendar.get(Calendar.YEAR);
      calendar.clear();
      return year;
     }
     /**
      * 获得日期的月
      *
      * @param _date 日期对象
      * @return 日期的月
      */
     public static int getMonth(java.util.Date _date) {
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      // 以0开始
      int month = calendar.get(Calendar.MONTH);
      calendar.clear();
      return (month + 1);
     }
     /**
      * 获得日期的天,以月为基
      *
      * @param _date 日期对象
      * @return 日期的天
      */
     public static int getDay(java.util.Date _date) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(_date);
      int day = calendar.get(Calendar.DAY_OF_MONTH);
      calendar.clear();
      return day;
     }
     /**
      * 获得日期的小时
      *
      * @param _date 日期对象
      * @return 日期的小时
      */
     public static int getHours(java.util.Date _date) {
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      int value = calendar.get(Calendar.HOUR);
      calendar.clear();
      return value;
     }
     /**
      * 获得日期的分钟
      *
      * @param _date 日期对象
      * @return 日期的分钟
      */
     public static int getMinutes(java.util.Date _date) {
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      int value = calendar.get(Calendar.MINUTE);
      calendar.clear();
      return value;
     }
     /**
      * 获得日期的小秒
      *
      * @param _date 日期对象
      * @return 日期的秒
      */
     public static int getSeconds(java.util.Date _date) {
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_date);
      int value = calendar.get(Calendar.SECOND);
      calendar.clear();
      return value;
     }
     /**
      * 计算两个日期间相隔的天数
      *
      * @param _startDate 起始日期
      * @param _endDate 终止日期
      * @return 相隔天数, 如果结果为正表示<b>_endDate</b>在<b>_startDate</b>之后;如果结果为负表示<b>_endDate</b>在<b>_startDate</b>之前;
      * 如果结果为0表示<b>_endDate</b>和<b>_startDate</b>是同一天。
      */
     public static int getDayCount(java.util.Date _startDate,java.util.Date _endDate) {
      Calendar calendar =  Calendar.getInstance();
      calendar.setTime(_startDate);
      int startDay = calendar.get(Calendar.DAY_OF_YEAR);
      int startYear = calendar.get(Calendar.YEAR);
      calendar.clear();
      calendar.setTime(_endDate);
      int endDay = calendar.get(Calendar.DAY_OF_YEAR);
      int endYear = calendar.get(Calendar.YEAR);
      calendar.clear();
      return (endYear - startYear) * 365 + (endDay - startDay);
     }
     /**
      * 获得两个Date间的月数, 天数超过14天算1个月
      *
      * @param _startDate 开始时间
      * @param _endDate 结束时间
      * @return 两个Date间的月数
      */
     public static int getMonthAmount(java.sql.Date _startDate,java.sql.Date _endDate) {
      int nYear = 0;
      int nMonth = 0;
      int nDay = 0;
      int nMonthAmount = 0;
      Calendar cldStart = Calendar.getInstance();
      Calendar cldEnd = Calendar.getInstance();
      cldStart.setTime(_startDate);
      cldEnd.setTime(_endDate);
      nYear = cldEnd.get(Calendar.YEAR) - cldStart.get(Calendar.YEAR);
      nMonth = cldEnd.get(Calendar.MONTH) - cldStart.get(Calendar.MONTH);
      nDay = cldEnd.get(Calendar.DATE) - cldStart.get(Calendar.DATE);
      if (nDay > 14) {
       nMonthAmount = nYear * 12 + nMonth + 1;
      } else {
       nMonthAmount = nYear * 12 + nMonth;
      }
      return nMonthAmount;
     }
     /**
      * 格式化长整形数
      *
      * @param _inStrObj 长整形字串对象
      * @return 长整形数
      */
     public static long toLong(Object _inStrObj) {
      if (_inStrObj == null || _inStrObj.toString().trim().equals("")) {
       return 0;
      } else {
       return Long.valueOf(_inStrObj.toString()).longValue();
      }
     }
     /**
      * 格式化整形数
      *
      * @param _inStrObj 整形数字串对象
      * @return 整形数
      */
     public static int toInteger(Object _inStrObj) {
      if (_inStrObj == null || _inStrObj.toString().trim().equals("")) {
       return 0;
      } else {
       return new Integer(_inStrObj.toString()).intValue();
      }
     }
     /**
      * 格式化双精浮点数
      *
      * @param _inStrObj 双精浮点数字串对象
      * @return 双精度浮点数,
      */
     public static double toDouble(Object _inStrObj) {
      if (_inStrObj == null || _inStrObj.toString().trim().equals("")) {
       return 0;
      } else {
       return Double.valueOf(_inStrObj.toString()).doubleValue();
      }
     }
     /**
      * 格式化浮点数
      *
      * @param _inStrObj 浮点数字串对象
      * @return 浮点数,如果数据格式错误,或字串为空,这返回0
      */
     public static float toFloat(Object _inStrObj) {
      if (_inStrObj == null || _inStrObj.toString().trim().equals("")) {
       return 0;
      } else {
       return Float.valueOf(_inStrObj.toString()).floatValue();
      }
     }
     /**
      * 将字节数组采用编码<b>_encoding</b>转化为字符串
      *
      * @param _bytes 字节数组
      * @param _encoding 编码方式
      * @throws ParamValidateException 如果编码方式不支持时掷出
      * @return 字符串
      */
     public static String toStr(byte[] _bytes, String _encoding) throws IllegalArgumentException{
      if( _bytes == null) {
       return null;
      }
      
      String s = null;
      try {
       s = new String(_bytes, _encoding);
      } catch (Exception e) {
       throw new IllegalArgumentException("不支持的编码方式:" + _encoding);
      }
      return s;
     }
     /**
      * 格式化布尔对象
      *
      * @param _boolean 布尔对象
      * @return 布尔对象的值,如果<b>_boolean</b>为null, 返回false
      */
     public static boolean toBoolean(Boolean _boolean) {
      if (_boolean == null) {
       return false;
      } else {
       return _boolean.booleanValue();
      }
     }
     /**
      * 获得对象的字符串表示, 当<b>_obj</b>为null时用<b>_replaceStr</b>替代
      *
      * @param _obj 对象
      * @param _replaceStr 替代null值的字符串
      * @return 处理后的字符串
      */
     public static String toStr(Object _obj, String _replaceStr) {
      if (_obj == null) {
       return _replaceStr;
      } else {
       return _obj.toString();
      }
     }
     
     /**
      * 字符串处理, 当<b>_str</b>为null时用<b>_replaceStr</b>替代
      *
      * @param _str 原始字符串
      * @param _replaceStr 替代null值的字符串
      * @return 处理后的字符串
      */
     public static String toStr(String _str, String _replaceStr) {
      if (_str == null||_str.equals("null")) {
       return _replaceStr;
      } else {
       return _str;
      }
     }
     /**
      * 字符串处理, 当<b>_str</b>为null时用<b>""</b>替代
      *
      * @param _str 原始字符串
      * @return 处理后的字符串
      */
     public static String toStr(String _str) {
      return toStr(_str, "");
     }
     /**
      * 获得对象的字符串表示, 当<b>_obj</b>为null时用<b>""</b>替代
      *
      * @param _obj 对象
      * @return 获得对象的字符串
      */
     public static String toStr(Object _obj) {
      if(_obj==null) {
       return "";
      }else{
       return toStr(_obj.toString());
      }
     }
     /**
      * 将字符串采用编码<b>_encoding</b>转化为字节数组
      *
      * @param _str 字符串
      * @param _encoding 编码方式
      * @throws ParamValidateException 如果编码方式不支持时掷出
      * @return 字节数组
      */
     public static byte[] toBytes(String _str, String _encoding) throws IllegalArgumentException{
      if( _str == null) {
       return null;
      }
      byte[] b = null;
      try {
       b = _str.getBytes(_encoding);
      } catch (Exception e) {
       throw new IllegalArgumentException("不支持的编码方式:" + _encoding);
      }
      return b;
     }
     /**
      * 将双精浮点数代表的金额转化中文大写形式
      *
      * @param _dMoney 代表双精浮点数的金额
      * @return 金额的中文大写形式,如果输入参数<b>dMoney</b>大于10^8或小于0.01返回空串。
      */
     public static String toChinese(double _dMoney) {
      String[] strArr = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
      String[] strArr1 = { "分", "角", "圆", "拾", "佰", "仟", "万", "拾", "佰", "仟" };
      String[] strArr2 = new String[10];
      String sRtn = "";
      int iTmp;
      double dTmp;
      try {
       _dMoney += 0.001;
       if ((_dMoney >= 100000000) || (_dMoney < 0.01)) {
        sRtn = "";
       } else {
        for (int i = 0; i < 10; i++) {
         dTmp = _dMoney / Math.pow(10, 7 - i);
         iTmp = (new Double(dTmp)).intValue();
         _dMoney -= iTmp * Math.pow(10, 7 - i);
         if (iTmp != 0) {
          strArr2[i] = strArr[iTmp] + strArr1[9 - i];
         } else {
          strArr2[i] = "";
         }
        }
        boolean bFlag = false;
        for (int i = 0; i < 10; i++) {
         if (!"".equals(strArr2[i])) {
          sRtn += strArr2[i];
          bFlag = true;
         } else {
          if (i == 3) {
           sRtn += "万";
           bFlag = true;
          } else if (i == 7) {
           sRtn += "圆";
           bFlag = true;
          } else if (bFlag) {
           sRtn += "零";
           bFlag = false;
          }
         }
        }
        if (sRtn.startsWith("万")) {
         sRtn = sRtn.substring(1, sRtn.length());
        }
        if (sRtn.startsWith("圆")) {
         sRtn = sRtn.substring(1, sRtn.length());
        }
        while (sRtn.startsWith("零")) {
         sRtn = sRtn.substring(1, sRtn.length());
        }
        if (sRtn.lastIndexOf("零") == (sRtn.length() - 1)) {
         sRtn = sRtn.substring(0, sRtn.length() - 1);
        }
        if (sRtn.startsWith("圆")) {
         sRtn = sRtn.substring(1, sRtn.length());
        }
        iTmp = sRtn.indexOf("圆");
        if (iTmp != -1) {
         if ("零".equals(sRtn.substring(iTmp - 1, iTmp))) {
          sRtn =
           sRtn.substring(0, iTmp - 1)
            + sRtn.substring(iTmp, sRtn.length());
         }
        }
        iTmp = sRtn.indexOf("万");
        if (iTmp != -1) {
         if ("零".equals(sRtn.substring(iTmp - 1, iTmp))) {
          sRtn =
           sRtn.substring(0, iTmp - 1)
            + sRtn.substring(iTmp, sRtn.length());
         }
        }
        while (sRtn.startsWith("零")) {
         sRtn = sRtn.substring(1, sRtn.length());
        }
        sRtn += "整";
       }
      } catch (Exception ex) {
      }
      return sRtn;
     }
     /**
      * 根据输入的String返回BigDecimal,或者若String非数字串,返回null
      *
      * @param _str  待转化的字符串
      * @return BigDecimal对象
      */
     public static BigDecimal toBigDecimal(String _str) {
      BigDecimal bd = null;
      if (_str != null) {
       try {
        bd = new BigDecimal(_str);
       } catch (Exception e) {
        return null;
       }
      }
      return bd;
     }
     /**
      * 根据年,月,日,转化为Timestamp类型,便于DB插入处理
      *
      * @param _sDate 格式为:yyyy-mm-dd
      * @return Timestamp的时间格式
      */
     public static Timestamp toTimestamp(String _sDate) {
      Timestamp ts = null;
      if (_sDate == null || "".equals(_sDate)) {
       return null;
      }
      ts = Timestamp.valueOf(_sDate + " 00:00:00.000000000");
      return ts;
     }
     /**
      * 替换Html文档中的"&nbsp"" ", "&lt""<", "&gt"">""<br>""\r\n"
      *
      * @param _rawStr 原始Html文档
      * @return 替换后的Html文档
      */
     public static String changeHtmlStr(String _rawStr) {
      String str = null;
      if (_rawStr != null) {
       str = replaceString( "&nbsp;", " ", _rawStr);
       str = replaceString( "&lt;","<", str);
       str = replaceString( "&gt;",">", str);
       str = replaceString( "&amp;","&", str);
       str = replaceString( "&quot;","\"", str);
       str = replaceString( "<br>", "\r\n",str);
      }
      return str;
     }
     /**
      * 使用新串替换原有字符串中老串
      *
      * @param _oldStr 待替换的字符串
      * @param _newStr 新字符串
      * @param _wholeStr 整个字符串
      * @return 替换后新串
      */
     public static String replaceString(String _oldStr,String _newStr,String _wholeStr) {
      if( _wholeStr == null){
       return null;
      }
      if( _newStr == null) {
       return _wholeStr;
      }
      
      int start=0, end=0;
      StringBuffer result=new StringBuffer();
       result=result.append(_wholeStr);
       while ( result.indexOf(_oldStr, start)>-1) {
          start=result.indexOf(_oldStr, start);
          end=start+_oldStr.length();
          result.replace(start,end,_newStr);
          start += _newStr.length();
       }
      return result.toString();
     }
     /**
      * 如果是正向替换,使用新串替换原有字符串中第一个老串;如果是逆向替换,使用新串替换原有字符串中最后一个老串
      *
      * @param _oldStr 待替换的字符串
      * @param _newStr 新字符串
      * @param _wholeStr 整个字符串
      * @param _reverse 替换方向,如果为false正向替换,否则逆向替换
      * @return 替换后新串
      */
     public static String replaceFirstString(String _oldStr,String _newStr,String _wholeStr, boolean _reverse) {
      if( _wholeStr == null){
       return null;
      }
      if( _newStr == null) {
       return _wholeStr;
      }
      StringBuffer result=new StringBuffer(_wholeStr);
      int start=0, end=0;
      if(!_reverse) {
       if (result.indexOf(_oldStr)>-1) {
        start=result.indexOf(_oldStr);
        end=start+_oldStr.length();
        result.replace(start,end,_newStr);
       }
      }else{
       if (result.lastIndexOf(_oldStr)>-1) {
        start=result.lastIndexOf(_oldStr);
        end=start+_oldStr.length();
        result.replace(start,end,_newStr);
       }
      }
      return result.toString();
     } 
     
     /**
      * 将字符串转换为HTML形式,以便在JavaScript中使用
      *
      * @param _sourceStr 原字符串
      * @return 转换后的字符串
      */
     public static String changeToHTMLStr(String _sourceStr) {
      if (_sourceStr == null) {
       return null;
      }
      StringBuffer buff = new StringBuffer(1024);
      int n = _sourceStr.length();
      char c;
      for (int i = 0; i < n; i++) {
       c = _sourceStr.charAt(i);
       if (c == '"') {
        buff.append('\\');
        buff.append(c);
       } else if (c == '\\') {
        buff.append('\\');
        buff.append(c);
       } else if (c == '\r') {
        buff.append("\\r");
       } else if (c == '\n') {
        buff.append("\\n");
       } else {
        buff.append(c);
       }
      }
      return buff.toString();
     }
     /**
      * 得到 _value截取小数点后_len位 以后的值
      *
      * @param _value 原值
      * @param _len 小数点后的位数
      * @return 截取以后的值
      */
     public static float roundFloat(float _value, int _len) throws IllegalArgumentException{
      int iLen = _len;
      checkParamPositive("_len", _len);
      float d = (float) Math.pow(10, iLen);
      float fValue = _value * d;
      return Math.round(fValue) / d;
     }
     /**
      * 获得float的字符串表示,首先对_value按_len进行四舍五入截位,如果截位后小数点后位数小于_len,则使用0补齐。
      *
      * @param _value 原值
      * @param _len 小数点后的位数
      * @return float的字符串
      */
     public static String formatFloat(float _value, int _len) throws IllegalArgumentException{
      String fStr = String.valueOf(roundFloat(_value, _len));
      StringBuffer sb = new StringBuffer(fStr);
      int leftBit = fStr.length() - fStr.indexOf(".") - 1;
      if (leftBit < _len) {
       for (int i = 0; i < (_len - leftBit); i++) {
        sb.append("0");
       }
      }
      return sb.toString();
     }
     /**
      * 得到 _value截取小数点后_len位 以后的值
      *
      * @param _value 原值
      * @param _len 小数点后的位数
      * @return 截取以后的值
      */
     public static double roundDouble(double _value, int _len) throws IllegalArgumentException {
      int iLen = _len;
      checkParamPositive("_len", _len);
      double d = Math.pow(10, iLen);
      double dValue = _value * d;
      return Math.round(dValue) / d;
     }
     /**
      * 获得double的字符串表示,首先对_value按_len进行四舍五入截位,如果截位后小数点后位数小于_len,则使用0补齐。
      *
      * @param _value 原值
      * @param _len 小数点后的位数
      * @return double的字符串
      */
     public static String formatDouble(double _value, int _len) throws IllegalArgumentException{
      String fStr = String.valueOf(roundDouble(_value, _len));
      StringBuffer sb = new StringBuffer(fStr);
      int leftBit = fStr.length() - fStr.indexOf(".") - 1;
      if (leftBit < _len) {
       for (int i = 0; i < (_len - leftBit); i++) {
        sb.append("0");
       }
      }
      return sb.toString();
     }
     
     
     /**
      * 获得字符串的左边<p>_len</p>个字符串
      *
      * @param _str 字符串
      * @param _len 长度
      * @return <p>_len</p>个字符串
      */
     public static String leftString(String _str, int _len) {
      if (_str == null) {
       return null;
      }
      if (_len < 0) {
       return "";
      }
      if (_str.length() <= _len) {
       return _str;
      } else {
       return _str.substring(0, _len);
      }
     }
     /**
      * 获得字符串的右边<p>_len</p>个字符串
      *
      * @param _str 字符串
      * @param _len 长度
      * @return 字符串的右边<p>_len</p>个字符串
      */ 
     public static String rightString(String _str, int _len) {
      if (_str == null) {
       return null;
      }
      if (_len < 0) {
       return "";
      }
      if (_str.length() <= _len) {
       return _str;
      } else {
       return _str.substring(_str.length() - _len);
      }
     }
     
     /**
      * 右填充字符<p>_padChar</p>,使整个字符串长度为<p>_size</p>
      *
      * @param _str 原始字符串
      * @param _size 添充后字符的总长度
      * @param _padChar 待填充字符
      * @return 右填充后的字符串,如:rightPad('hell', 3, '0')=hell;rightPad('hell', 10, '0')=hell000000
      */
     public static String rightPad(String _str, int _size, char _padChar) {
      if (_str == null) {
       return null;
      }
      int pads = _size - _str.length();
      if (pads <= 0) {
       return _str; // returns original String when possible
      }
      return _str.concat(padding(pads, _padChar));
     }
     /**
      * 左填充字符<p>_padChar</p>,使得填充后的字符串总长为<p>_size</p>
      *
      * @param _str 原始字符串
      * @param _size 添充后字符的总长度
      * @param _padChar 待填充字符
      * @return 左填充后的字符串,如:leftPad('hell', 10, '0')=000000hell;leftPad('hell', 3, '0')=hell
      */
     public static String leftPad(String _str, int _size, char _padChar) {
      if (_str == null) {
       return null;
      }
      int pads = _size - _str.length();
      if (pads <= 0) {
       return _str; // returns original String when possible
      }
      return padding(pads, _padChar).concat(_str);
     } 
     /**
      * 字符串<p>padChar</p>重复<p>repeat</p>位
      *
      * @param _repeat 重复次数
      * @param _padChar 待重复字符
      * @return 重复后的结果字串,如:padding(5, 'a')=aaaaa;padding(0, 'a'):""
      */
     private static String padding(int _repeat, char _padChar) {
      String value = "";
      String padStr = String.valueOf(_padChar);
      if(_repeat>0) {
       for(int i = 0;i<_repeat;i++) {
        value = value.concat(padStr);
       }
      }
      return value;
     }
     
     private static void checkParamPositive(String _str, int _value) throws IllegalArgumentException  {
      if (_value <= 0) {
       throw new IllegalArgumentException("参数:" + _str + "不能小于等于0");
      }
     }
     
    }
    
  • com.primeton.example.excel.ExcelTemplate:
    
    package com.primeton.example.excel;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Vector;
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.Region;
    import org.apache.poi.poifs.filesystem.POIFSFileSystem;
    import com.eos.data.xpath.XPathLocator;
    import com.eos.foundation.data.DataObjectUtil;
    import com.eos.foundation.database.DatabaseUtil;
    import com.primeton.data.sdo.impl.PropertyImpl;
    import com.primeton.data.sdo.impl.TypeReference;
    import com.primeton.data.sdo.impl.types.BooleanType;
    import com.primeton.data.sdo.impl.types.DateTimeType;
    import com.primeton.data.sdo.impl.types.DateType;
    import com.primeton.data.sdo.impl.types.DecimalType;
    import com.primeton.data.sdo.impl.types.FloatType;
    import com.primeton.data.sdo.impl.types.IntType;
    import com.primeton.data.sdo.impl.types.IntegerType;
    import com.primeton.data.sdo.impl.types.LongType;
    import commonj.sdo.DataObject;
    import commonj.sdo.Type;
    /**
     *
     * Excel模板实现类<BR>
     * 实现通过自定义Excel数据模版,将结果集填充到模版相应位置,自动创建输出到指定的文件,允许Excel模版设置公式,调用方法如下:<BR>
     * <pre>
     *     ExcelTemplate template=new ExcelTemplate(templateFilePath,outputFilePath)
     *     //template.setIncludeFormula(true);设置包含公式
     *     template.generate(ResultSet);//resultset为ArrayList对象,数据行以Map封装
     *     //template.generate(titleMap,dataList)//显示主表、明细表信息
     * </pre>
     *
     * @author primeton
     * wengzr (mailto:)
     */
    public class ExcelTemplate {
     /**
      * 模板文件名
      */
     private String templateFile;
     /**
      * 输出文件名
      */
     private String outputFile;
     /**
      * Excel模板定义的输出字段名数组
      */
     private String[] fieldNames;
     /**
      * 输出的起始行,默认为-1,不输出
      */
     private int startRow=-1;
     private int tempStartRowNum=-1;
     /**
      * 默认字体大小
      */
     private int fontSize=10;
     /**
      * 默认字体
      */
     private String fontName="宋体";
     /**
      * 是否设置信息标题栏边框,默认情况不设置边框
      */
     private boolean titleCellBold=false;
     /**
      * 是否设置空白栏边框,默认情况不设置边框
      */
     private boolean blankCellBold=false;
     /**
      * 是否自动分工作薄
      */
     private boolean autoSheet=false;
     /**
      * 是否自动分页
      */
     private boolean autoPagination=false;
     /**
      * 分页行数
      */
     private int maxrow=-1;
     /**
      * 是否有公式
      */
     private boolean hasFormula=false;
     /**
      * 关键字
      * &-表示模版信息内容字段
      * #-表示模版明细内容字段
      * formula-表示模版函数关键字
      * ~-表示Cell当前行,当包含":"时,表示当前行减1
      */
     private final String TITLE_FLAG="&";
     private final String CONTENT_FLAG="#";
     private final String FORMULA_FLAG="formula";
     private final String UNLIMIT_FLAG="~";
     private final String FIELD_AUTO_ID="_id";
     /**
      * 公式计算操作符号
      */
     private final String[] OP_FLAG=new String[]{"+","-","*","/","%",":"};
     /**
      * 默认构造函数
      *
      */
     public ExcelTemplate(){
     }
     /**
      * 构造器
      * @param templateFile 模版文件
      * @param outputFile 输出文件
      */
     public ExcelTemplate(String templateFile,String outputFile){
      this.templateFile=templateFile;
      this.outputFile=outputFile;
     }
     /**
      * 设置模版文件是否包含Excel公式
      * @param hasFormula
      */
     public void setIncludeFormula(boolean hasFormula){
      this.hasFormula=hasFormula;
     }
     /**
      * 设置标题栏是否需要边框
      * @param b
      */
     public void setTitleCellBold(boolean titleCellBold){
      this.titleCellBold=titleCellBold;
     }
     /**
      * 设置空白行是否需要显示边框
      * @param blankCellBold
      */
     public void setBlankCellBold(boolean blankCellBold){
      this.blankCellBold=blankCellBold;
     }
     /**
      * 设置是否分工作薄
      * @param b
      */
     public void setAutoSheet(boolean autoSheet){
      this.autoSheet=autoSheet;
      this.autoPagination=(autoSheet?false:autoPagination);
     }
     /**
      * 是否自动分页
      * @param autoPagination
      */
     public void setAutoPagination(boolean autoPagination){
      this.autoPagination=autoPagination;
      this.autoSheet=(autoPagination?false:autoSheet);
     }
     /**
      * 设置分页最大行
      * @param maxrow
      */
     public void setMaxRow(int maxrow){
      this.maxrow=maxrow;
     }
     /**
      * 设置字体大小,默认10号字体
      * @param size
      */
     public void setFontSize(int size){
      this.fontSize=size;
     }
     public void setFontName(String fontName){
      this.fontName=fontName;
     }
     /**
      * 初始化工作模版,获取模版配置起始行(start)以及对应字段填充位置(fieldNames)
      * @param sheet
      */
     private void initialize(HSSFSheet sheet){
            boolean setStart=false;
            int rows  = sheet.getPhysicalNumberOfRows();
            for (int r = 0; r < rows; r++){
                HSSFRow row   = sheet.getRow(r);
                if (row != null) {
                    int cells = row.getPhysicalNumberOfCells();
                    for(short c = 0; c < cells; c++){
                     HSSFCell cell  = row.getCell(c);
                     if(cell!=null)
                     {
                      String value=null;
                      if(cell.getCellType()==HSSFCell.CELL_TYPE_NUMERIC){
                       value=""+cell.getNumericCellValue();
                      }else if(cell.getCellType()==HSSFCell.CELL_TYPE_BOOLEAN){
                       value=""+cell.getBooleanCellValue();
                      }else{
                       value=cell.getRichStringCellValue().getString();
                      }
                         if(value!=null&&!"".equals(value))
                         {
                          value=value.trim();
                          //内容数据
                          if(value.startsWith(CONTENT_FLAG)){
                              if(!setStart){
                               this.startRow=r;//设置内容填充起始行
                               this.fieldNames=new String[cells];
                               setStart=true;
                              }
                              this.fieldNames[c]=value.substring(1);//初始化内容字段
                          }
                         }
                     }
                    }
                }
            }
     }
     /**
      * 计算公式,默认范围从0行到工作薄结尾
      * @param wb
      * @param sheet
      */
     private void calcFormula(HSSFWorkbook wb,HSSFSheet sheet){
      this.calcFormula(wb,sheet,0,sheet.getPhysicalNumberOfRows());
     }
     /**
      * 计算公式函数,范围从开始行(start_row)到结束行(end_row)
      * @param wb HSSFWorkbook
      * @param sheet HSSFSHeet
      * @param start_rang
      * @param end_rang
      */
     private void calcFormula(HSSFWorkbook wb,HSSFSheet sheet,int start_rang,int end_rang){
            //int rows  = sheet.getPhysicalNumberOfRows();
      HSSFCellStyle borderStyle=this.getBorderStyle(wb);
      HSSFCellStyle noneStyle=this.getNoneStyle(wb);  
            for (int r = start_rang; r < end_rang; r++){
                HSSFRow row   = sheet.getRow(r);
                if (row != null) {
                    int cells = row.getPhysicalNumberOfCells();
                    for(short c = 0; c < cells; c++){
                     HSSFCell cell  = row.getCell(c);
                     if(cell!=null){
                      if(cell.getCellType()==HSSFCell.CELL_TYPE_STRING){
                             String value=cell.getRichStringCellValue().getString();
                             if(value!=null){
                              value=value.trim().toLowerCase();
                              if(value.startsWith(FORMULA_FLAG))
                              {
                               int index=value.indexOf("=");
                               String formula=value.substring(index+1);
                               //判断函数是否包含以#开头,如果是以#开头表示必须显示边框,
                               String flag=formula.substring(0,1);
                               boolean showBold=false;
                               if(flag.equals(CONTENT_FLAG)){
                                formula=formula.substring(1);
                                showBold=true;
                               }
                                 //如果包含':'符号则统计公式不包含当前行,否则会引发公式循环引用错误.
                               if(formula.indexOf(":")!=-1){
                                formula=formula.replaceAll(UNLIMIT_FLAG,r+"").toUpperCase();
                               }else{
                                formula=formula.replaceAll(UNLIMIT_FLAG,(r+1)+"").toUpperCase();
                               }
                               //判断公式对应的Cell内容是否为blank,
                               //如果公式对应的CELL内容为空,则设置为""
                               int rightIndex=formula.indexOf(")");
                               int leftIndex=formula.indexOf("(");
                               String content=formula.substring(leftIndex+1,rightIndex);
                               int opIndex=this.getOpIndex(content);
                               String startPos=content.substring(0,opIndex);
                               String endPos=content.substring(opIndex+1);
                               int start_col=this.getColumnIndex(startPos.charAt(0));
                            int start_row=Integer.parseInt(startPos.substring(1));
                            int end_col=this.getColumnIndex(endPos.charAt(0));
                            int end_row=Integer.parseInt(endPos.substring(1));
                            HSSFCell startC=sheet.getRow(start_row-1).getCell((short)start_col);
                            HSSFCell endC=sheet.getRow(end_row-1).getCell((short)end_col);
                            //判断公式开始Cell与结束cell内容是否无效
                            //当为均为无效的cell值,并且当前公式不包含":",则设置公式框内容为"",
                            //包含":" 则设置为计算公式
                            if(invalidCellValue(startC)&&invalidCellValue(endC)){
                             if(formula.indexOf(":")==-1){
                              cell.setCellValue( new HSSFRichTextString(""));
                             }else{
                                    cell=row.createCell((short)c);
                                    cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
                                    cell.setCellFormula(formula);
                             }
                            }else{
                                //重建Cell
                                cell=row.createCell((short)c);
                                cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
                                cell.setCellFormula(formula);
                            }
                               if(showBold){
                                cell.setCellStyle(borderStyle);
                               }else{
                                cell.setCellStyle(noneStyle);
                               }
                              }
                             }
                      }
                     }
                    }
                }
            }
     }
     /**
      * 设置公式文本框为空白栏,当统计开始行减1==startRowNum时
      * @param cell
      * @param startRowNum
      */
     private void setFormulaBlankCell(HSSFCell cell,int startRowNum){
         if (cell != null) {
       if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
        String value = cell.getRichStringCellValue().getString();
        if (value != null) {
         value = value.trim().toLowerCase();
         if (value.startsWith(FORMULA_FLAG)) {
          int index = value.indexOf("=");
          String formula = value.substring(index + 1);
          String flag = formula.substring(0, 1);
          if (flag.equals(CONTENT_FLAG))formula = formula.substring(1);
          if (formula.indexOf(":") != -1) {
           int rightIndex = formula.indexOf(")");
           int leftIndex = formula.indexOf("(");
           String content = formula.substring(leftIndex + 1,rightIndex).toUpperCase();
           int opIndex = this.getOpIndex(content);
           String startPos = content.substring(0, opIndex);
           String colValue = startPos.substring(1,opIndex);
           if(Integer.parseInt(colValue)-1==startRowNum)
            cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
          }
         }
        }
       }
      }
     
     }
     /**
      * 生成填充模版标题数据
      *
      * @param titleMap
      * @param wb
      * @param sheet
      * @throws Exception
      */
     private void generateTitleDatas(DataObject exportInfo,HSSFWorkbook wb,HSSFSheet sheet)throws Exception{
            int rows  = sheet.getPhysicalNumberOfRows();
            HSSFCellStyle borderStyle=this.getBorderStyle(wb);
            HSSFCellStyle noneStyle=this.getNoneStyle(wb);       
            for (int r = 0; r < rows; r++){
                HSSFRow row   = sheet.getRow(r);
                if (row != null) {
                    int cells =row.getPhysicalNumberOfCells();
                    for(short c = 0; c < cells; c++){
                     HSSFCell cell  = row.getCell(c);
                     if(cell!=null){
                      if(cell.getCellType()==HSSFCell.CELL_TYPE_STRING){
                             String value=cell.getRichStringCellValue().getString();
                             if(value!=null){
                              value=value.trim();
                              if(value.startsWith(TITLE_FLAG)){
                               value=value.substring(1);
                               //获取对应的值,支持XPATH取值
                               Object obj=XPathLocator.newInstance().getValue(exportInfo, value);
                               String content=obj+"";
                               //String content=exportInfo.getString(value);
                               if(content==null)content="";
                               //重建Cell,填充标题值
                               cell=row.createCell((short)c);                           
                               cell.setCellType(HSSFCell.CELL_TYPE_STRING);                           
                               cell.setCellValue( new HSSFRichTextString(content));
                               if(!titleCellBold){
                                cell.setCellStyle(noneStyle);
                               }else{
                                cell.setCellStyle(borderStyle);
                               }
                              }
                             }
                      }
                     }
                    }
                }
            }
     }
    
     /**
      * 将指定的对象数组resulset输出到指定的Excel位置
      * @param resultset List<DataObject>对象数组
      * @param wb HSSFWorkbook
      * @param sheet HSSFSheet
      */
     private void generateContentDatas(List<DataObject> resultset,HSSFWorkbook wb,HSSFSheet sheet){
      HSSFCellStyle borderStyle=this.getBorderStyle(wb);
      HSSFCellStyle noneStyle=this.getNoneStyle(wb);
      //默认行号
      int autoRowId=1;
            for(Iterator it=resultset.iterator();it.hasNext();autoRowId++){
             DataObject content=(DataObject)it.next();
             HSSFRow sourceRow=sheet.getRow(startRow);
             HSSFRow row=sheet.createRow(startRow++);
             for(int i=0;i<sourceRow.getPhysicalNumberOfCells();i++){
              //输出自动生成的行号
              if(fieldNames[i]!=null&&fieldNames[i].equals(FIELD_AUTO_ID)){
                 HSSFCell cell=row.createCell((short)i);           
               cell.setCellStyle(borderStyle);
               cell.setCellType(HSSFCell.CELL_TYPE_STRING);
            cell.setCellValue(autoRowId);
            continue;
              }
              if(fieldNames[i]!=null){
               HSSFCell cell=row.createCell((short)i);           
               cell.setCellStyle(borderStyle);
               if(content!=null){
                //字段名支持xpath取值
                Object value=XPathLocator.newInstance().getValue(content, fieldNames[i]);
                   //Object value=content.get(fieldNames[i]);
                   if(value!=null){
                    if(value instanceof Double|| value instanceof BigDecimal){
                     cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
                     cell.setCellValue(Double.parseDouble(value.toString()));
                    }else{
                     cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                     cell.setCellValue(new HSSFRichTextString(value.toString()));
                    }
                   }else{
                    cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
                   }
               }else{
                cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
                if(!blankCellBold){
                 cell.setCellStyle(noneStyle);
                }else{
                 cell.setCellStyle(borderStyle);
                }
               }
              }else{
            HSSFCell sourceCell=sourceRow.getCell((short)i);
            if(sourceCell!=null&&
              sourceCell.getCellType()==HSSFCell.CELL_TYPE_STRING&&
              sourceCell.getRichStringCellValue().getString()!=null&&
              sourceCell.getRichStringCellValue().getString().toLowerCase().startsWith(FORMULA_FLAG)){
             HSSFCell cell=row.createCell((short)i);
             cell.setCellType(HSSFCell.CELL_TYPE_STRING);
             cell.setCellValue(sourceCell.getRichStringCellValue());
            }
           }
             }
             if(it.hasNext()){
              //向下平推一行
              //sheet.shiftRows(startRow-1,sheet.getLastRowNum(),1);
              shiftDown(sheet,startRow-1, sheet.getLastRowNum(), 1);
             }
            }
     }
     /**
      * 将结果集填充到Excel模版,resultset必须是以Map封装行
      * @param
      * @param resultset 数据内容
      * @throws Exception
      */
     public void generate(List<DataObject> resultset)throws Exception{
      this.generate(resultset,null);
     }
     /**
      * 将结果集填充到Excel模版,resultset必须是以Map封装行
      * @param titleMap 标题信息
      * @param resultset 结果集
      * @throws Exception
      */
     public void generate(List<DataObject> resultset,DataObject exportInfo)throws Exception{
            POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream(templateFile));
            HSSFWorkbook wb = new HSSFWorkbook(fs);
            HSSFSheet sheet = wb.getSheetAt(0);
            initialize(sheet);
            if(startRow==-1)
             return ;
    
            if(this.autoPagination){
             this.generatePagination(wb,sheet,resultset,exportInfo);
            }
            else if(this.autoSheet){
             generatePaginationSheet(wb,sheet,resultset,exportInfo);
            }
            else{
                //先填充标题
                if(exportInfo!=null)
                 this.generateTitleDatas(exportInfo,wb,sheet);
                //生成数据内容
                this.generateContentDatas(resultset,wb,sheet);
                if(hasFormula){
                 this.calcFormula(wb,sheet);
                }
            }
            FileOutputStream fileOut = new FileOutputStream(outputFile);
            wb.write(fileOut);
            fileOut.close();
     }
     /**
      * EXCEL分页
      * 必须在EXCEL模版的最后一行插入EXCEL分页符!
      * @param wb HSSFWorkbook
      * @param sourceSheet HSSFSheet
      * @param resultset 填充数据集
      * @param titleMap 信息栏内容
      * @throws Exception
      */
     private void generatePagination(HSSFWorkbook wb,HSSFSheet sourceSheet,List<DataObject> resultset,DataObject exportInfo)
    throws Exception{
         int startPosition=startRow;
         tempStartRowNum=startRow;
         int count=resultset.size() / maxrow;
         int num=resultset.size() % maxrow;
         int rows=sourceSheet.getPhysicalNumberOfRows();
         System.out.println("rows="+rows);
         if(num>0){
          count=count+1;
          num=maxrow-num;
          //不足指定的maxrow,添加空行
          for(int i=0;i<num;i++){
           resultset.add(null);
          }
         }
         //删除最后一行的分页符
         try{
          sourceSheet.removeRowBreak(rows-1);
         }catch(NullPointerException npe){
          throw new Exception("指定的EXCEL模版文件["+this.templateFile+"] 未插入分页符");
         }
         //超过1页则插入分页符
         for(int i=1;i<count;i++){
          //设置分页符
          sourceSheet.setRowBreak(i*rows-1);
          this.copyRows(sourceSheet,sourceSheet,0,rows,i*rows+1);
         }
         if(exportInfo!=null)
          this.generateTitleDatas(exportInfo,wb,sourceSheet);
         int current_page=0;
         while(current_page<count){
          List<DataObject> newList=resultset.subList(current_page*maxrow,maxrow*(current_page+1));
          this.generateContentDatas(newList,wb,sourceSheet);
          current_page++;
          //计算下一行的数据填充起始位置
          startRow=current_page*rows+maxrow+startPosition;
         }
            if(hasFormula)
             this.calcFormula(wb,sourceSheet);
     }
    
     /**
      * 生成分页的工作薄模版
      * @param wb HSSFWorkbook
      * @param sourceSheet HSSFSheet
      * @param resultset 填充数据集
      * @param titleMap 信息(标题)栏内容
      */
     private void generatePaginationSheet(HSSFWorkbook wb,HSSFSheet sourceSheet,List<DataObject> resultset,DataObject exportInfo)
    throws Exception{
         int startPosition=startRow;
         int count=resultset.size() / maxrow;
         int num=resultset.size() % maxrow;
         if(num>0){
          count=count+1;
          num=maxrow-num;
          //不足指定的maxrow,添加空行
          for(int i=0;i<num;i++){
           resultset.add(null);
          }
         }
         for(int i=1;i<count;i++){
          HSSFSheet newsheet=wb.createSheet("Page "+i);
          this.copyRows(sourceSheet,newsheet,0,sourceSheet.getLastRowNum(),0);
         }
         if(count>1){
          for(int i=0;i<wb.getNumberOfSheets();i++){
           startRow=startPosition;
           List<DataObject> newList=resultset.subList(i*maxrow,maxrow*(i+1));
           HSSFSheet sheet=wb.getSheetAt(i);
                 //先填充标题
                 if(exportInfo!=null)
                  this.generateTitleDatas(exportInfo,wb,sheet);
                    this.generateContentDatas(newList,wb,sheet);
                    if(hasFormula)
                     this.calcFormula(wb,sheet);
          }
         }else{
       HSSFSheet sheet=wb.getSheetAt(0);
             if(exportInfo!=null)
              this.generateTitleDatas(exportInfo,wb,sheet);
                this.generateContentDatas(resultset,wb,sheet);
                if(hasFormula)
                 this.calcFormula(wb,sheet);
         }
     }
     private HSSFCellStyle getBorderStyle(HSSFWorkbook wb){
            HSSFCellStyle style = wb.createCellStyle();
            HSSFFont font=wb.createFont();
            font.setFontHeightInPoints((short)fontSize);
            font.setFontName(fontName);
            style.setFont(font);
            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            return style;
     }
     private HSSFCellStyle getNoneStyle(HSSFWorkbook wb){
            HSSFCellStyle style = wb.createCellStyle();
            HSSFFont font=wb.createFont();
            font.setFontHeightInPoints((short)fontSize);
            font.setFontName(fontName);
            style.setFont(font);
            style.setBorderBottom(HSSFCellStyle.BORDER_NONE);
            style.setBorderLeft(HSSFCellStyle.BORDER_NONE);
            style.setBorderRight(HSSFCellStyle.BORDER_NONE);
            style.setBorderTop(HSSFCellStyle.BORDER_NONE);
            return style;
     }
    
     /**
         * 向下平推表格,并复制格式与内容
         * @param thisrow:当前行号
         * @param lastrow:最后行号
         * @param shiftcount:平推量
         */
        private void shiftDown(HSSFSheet sheet,int thisrow, int lastrow, int shiftcount) {
            sheet.shiftRows(thisrow, lastrow, shiftcount);
            for (int z = 0; z < shiftcount; z++) {
                HSSFRow row = sheet.getRow(thisrow);
                HSSFRow oldrow = sheet.getRow(thisrow + shiftcount);
                //将各行的行高复制
                oldrow.setHeight(row.getHeight());
                //将各个单元格的格式复制
                for (short i = 0; i <= oldrow.getPhysicalNumberOfCells(); i++) {
                    HSSFCell cell = row.createCell(i);
                    HSSFCell oldcell = oldrow.getCell(i);
                    if (oldcell != null) {                   
                        switch(oldcell.getCellType()){
                        case HSSFCell.CELL_TYPE_STRING:
                         cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                         cell.setCellValue(oldcell.getRichStringCellValue());
                         break;
                        case HSSFCell.CELL_TYPE_NUMERIC:
                         cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
                         cell.setCellValue(oldcell.getNumericCellValue());
                         break;
                        default:
                         cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                         cell.setCellValue(oldcell.getRichStringCellValue());
                        }
                        cell.setCellStyle(oldcell.getCellStyle());
                     }
                }
                //将有列跨越的复制
                Vector regs = findRegion(sheet,oldrow);
                if (regs.size() != 0) {
                    for (int i = 0; i < regs.size(); i++) {
                        Region reg = (Region) regs.get(i);
                        reg.setRowFrom(row.getRowNum());
                        reg.setRowTo(row.getRowNum());
                        sheet.addMergedRegion(reg);
                    }
                }
                thisrow++;
            }
        }
         /**
         * 查找所有的合并单元格
         * @param oldrow
         * @return
         */
        private Vector findRegion(HSSFSheet sheet ,HSSFRow oldrow) {
            Vector<Region> regs = new Vector<Region>();
            int num = sheet.getNumMergedRegions();
            int curRowid = oldrow.getRowNum();
            for (int i = 0; i < num; i++) {
                Region reg = sheet.getMergedRegionAt(i);
                if (reg.getRowFrom() == reg.getRowTo() && reg.getRowFrom() == curRowid) {
                    regs.add(reg);
                }
            }
            return regs;
        }
    
        /**
         * 复制EXCEL行到指定的工作薄上
         * ××如果是分页显示,需要增加一个判断:当复制行包含公式forumla=sum(G7:G~)字样时候,必须修改其实行G7为相应的新行。
         * @param sourceSheet  原工作薄
         * @param targetSheet 目标工作薄
         * @param pStartRow 复制起始行
         * @param pEndRow 复制终止行
         * @param pPosition 插入位置
         */
        private void copyRows(HSSFSheet sourceSheet, HSSFSheet targetSheet,int pStartRow, int pEndRow, int pPosition) {
      HSSFRow sourceRow = null;
      HSSFRow targetRow = null;
      HSSFCell sourceCell = null;
      HSSFCell targetCell = null;
      Region region = null;
      int cType;
      int i;
      short j;
      int targetRowFrom;
      int targetRowTo;
      if ((pStartRow == -1) || (pEndRow == -1)) {
       return;
      }
      // 拷贝合并的单元格
      for (i = 0; i < sourceSheet.getNumMergedRegions(); i++) {
       region = sourceSheet.getMergedRegionAt(i);
       if ((region.getRowFrom() >= pStartRow)&& (region.getRowTo() <= pEndRow)) {
        targetRowFrom = region.getRowFrom() - pStartRow + pPosition;
        targetRowTo = region.getRowTo() - pStartRow + pPosition;
        region.setRowFrom(targetRowFrom);
        region.setRowTo(targetRowTo);
        targetSheet.addMergedRegion(region);
       }
      }
      // 设置列宽
      for (i = pStartRow; i <= pEndRow; i++) {
       sourceRow = sourceSheet.getRow(i);
       if (sourceRow != null) {
        for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++) {
         targetSheet.setColumnWidth(j, sourceSheet.getColumnWidth(j));
        }
        break;
       }
      }
      // 拷贝行并填充数据
      for (; i <= pEndRow; i++) {
       sourceRow = sourceSheet.getRow(i);
       if (sourceRow == null) {
        continue;
       }
       targetRow = targetSheet.createRow(i - pStartRow + pPosition);
       targetRow.setHeight(sourceRow.getHeight());
       for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++) {
        sourceCell = sourceRow.getCell(j);
        if (sourceCell == null) {
         continue;
        }
        targetCell = targetRow.createCell(j);    
        targetCell.setCellStyle(sourceCell.getCellStyle());
        cType = sourceCell.getCellType();
        targetCell.setCellType(cType);
        switch (cType) {
        case HSSFCell.CELL_TYPE_BOOLEAN:
         targetCell.setCellValue(sourceCell.getBooleanCellValue());
         break;
        case HSSFCell.CELL_TYPE_ERROR:
         targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
         break;
        case HSSFCell.CELL_TYPE_FORMULA:
         targetCell.setCellFormula(parseFormula(sourceCell.getCellFormula()));
         break;
        case HSSFCell.CELL_TYPE_NUMERIC:
         targetCell.setCellValue(sourceCell.getNumericCellValue());
         break;
        case HSSFCell.CELL_TYPE_STRING:
         targetCell.setCellValue(sourceCell.getRichStringCellValue());
         break;
        }
        if(this.autoPagination){
         this.setFormulaBlankCell(sourceCell,tempStartRowNum);
        }
       }
      }
     }
        private String parseFormula(String pPOIFormula) {
      final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$
      StringBuffer result = null;
      int index;
      result = new StringBuffer();
      index = pPOIFormula.indexOf(cstReplaceString);
      if (index >= 0) {
       result.append(pPOIFormula.substring(0, index));
       result.append(pPOIFormula.substring(index+ cstReplaceString.length()));
      } else {
       result.append(pPOIFormula);
      }
      return result.toString();
     }
     
        /**
      * 将列的索引换算成ABCD字母,这个方法要在插入公式时用到
      * @param colIndex 列索引。
      * @return ABCD字母。
      */
        /*
        private String getColLetter(int colIndex){
         String ch = "";
            if (colIndex  < 26)
                ch = "" + (char)((colIndex) + 65);
            else
               ch = "" + (char)((colIndex) / 26 + 65 - 1) + (char)((colIndex) % 26 + 65);
            return ch;
        }
        */
        private int getColumnIndex(char c){
         int i=c;
         return i-65;
        }
        private int getOpIndex(String s){
         for(int i=0;i<OP_FLAG.length;i++){
          int index=s.indexOf(OP_FLAG[i]);
          if(index!=-1){
           return index;
          }
         }
         return -1;
        }
        /**
         * 判断是否无效Cell
         * @param cell
         * @return
         */
        private boolean invalidCellValue(HSSFCell cell){
         if(cell.getCellType()==HSSFCell.CELL_TYPE_BLANK){
          return true;
         }
         else if(cell.getCellType()==HSSFCell.CELL_TYPE_STRING){
          if(cell.getRichStringCellValue().getString()==null||cell.getRichStringCellValue().getString().equals("")){
           return true;
          }
         }
         else if(cell.getCellType()==HSSFCell.CELL_TYPE_ERROR){
          return true;
         }
         return false;
        }
        /**
         * 将目标Excel文件的内容导入到数据表
         * @param targetFile Excel文件路径
         * @param entityName SDO数据实体全名
         * @return 返回1 导入成功
         *
         * @throws Exception
         */
        public int importData(String targetFile,String entityName,int submitCount)throws Exception{
            POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream(targetFile));
            HSSFWorkbook wb = new HSSFWorkbook(fs);
            for(int sheetCount=0;sheetCount<wb.getNumberOfSheets();sheetCount++){
             HSSFSheet sheet = wb.getSheetAt(sheetCount);
             int rows  = sheet.getPhysicalNumberOfRows();
                initialize(sheet);
                if(startRow==-1)
                 continue;
                List<DataObject> dataObjects=new ArrayList<DataObject>();
                //第一行为#字段名
                //第二行为字段标题,因此内容读取从startRow+2
                for(int rowCount=startRow+2;rowCount<rows;rowCount++){
                 HSSFRow sourceRow=sheet.getRow(rowCount);
                 DataObject importEntity=DataObjectUtil.createDataObject(entityName);
                 //判断某一行是否允许插入,当该行的所有列cell均为BLANK时不插入数据库
                 boolean allowInsert=false;
                 //以下构造导入的实体对象,并根据Excel单元格的内容填充实体属性值
                 for(int cellCount=0;cellCount<fieldNames.length;cellCount++){
                  String propertyName=fieldNames[cellCount];
                  HSSFCell cell=sourceRow.getCell((short)cellCount);
                  if(cell.getCellType()==HSSFCell.CELL_TYPE_BLANK)
                   continue;
                  allowInsert=true;
                  String value=null;
                  if(cell.getCellType()==HSSFCell.CELL_TYPE_NUMERIC){
                    if (HSSFDateUtil.isCellDateFormatted(cell)){
                                 SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                 value= dateFormat.format((cell.getDateCellValue()));
                             
                              }else{ 
                                 value=String.valueOf((long) cell.getNumericCellValue()); 
                              }
                  }else if(cell.getCellType()==HSSFCell.CELL_TYPE_BOOLEAN){
                   value=cell.getBooleanCellValue()+"";
                  }else{
                   value=cell.getRichStringCellValue().getString();
                  }
                  TypeReference typeReference=(TypeReference)importEntity.getType().getProperty(propertyName).getType();
                  Type propertyType=typeReference.getActualType();
                  if(propertyType instanceof IntType||propertyType instanceof IntegerType){
                   //防止可能出现的Excel表格读取自动加.号
                     if(value.indexOf(".")!=-1)
                    value=value.substring(0,value.indexOf("."));
                   importEntity.set(fieldNames[cellCount],ChangeUtil.toInteger(value));
                  }
                  else if(propertyType instanceof BooleanType){
                   importEntity.set(fieldNames[cellCount],ChangeUtil.toBoolean(Boolean.valueOf(value)));
                  }
                  else if(propertyType instanceof FloatType){
                   importEntity.set(fieldNames[cellCount],ChangeUtil.toFloat(value));
                  }
                  else if(propertyType instanceof LongType){
                   if(value.indexOf(".")!=-1)
                    value=value.substring(0,value.indexOf("."));
                   importEntity.set(fieldNames[cellCount],ChangeUtil.toLong(value));
                  }
                  else if(propertyType instanceof DecimalType){
                   importEntity.set(fieldNames[cellCount],ChangeUtil.toBigDecimal(value));
                  }
                  else if(propertyType instanceof DateType){
                   importEntity.set(fieldNames[cellCount],ChangeUtil.changeToDBDate(value));
                  }
                  else if(propertyType instanceof DateTimeType){
                   importEntity.set(fieldNames[cellCount],ChangeUtil.toTimestamp(value));
                  }
                  else{
                   importEntity.set(fieldNames[cellCount], value);
                  }
                 }
    
                 if(dataObjects.size()<submitCount){
                  if(allowInsert)
                   dataObjects.add(importEntity);
                 }else{
                  if(dataObjects.size()>0){
                   DatabaseUtil.insertEntityBatch("default", dataObjects.toArray(new DataObject[dataObjects.size()]));
                   dataObjects.clear();
                  }
                 }
                 if(rowCount==rows-1){
                  if(dataObjects.size()>0)
                   DatabaseUtil.insertEntityBatch("default", dataObjects.toArray(new DataObject[dataObjects.size()]));
                 }
    
                }
            }
            return 1;
        }
    
        /**
         * 如果模板文件是否存在
         * @param filename 模板文件名
         * @return 文件存在返回true,否则false
         * @throws IOException
         */
        protected boolean isExistTemplate(String templateFile)throws IOException{
         File file=new File(templateFile);
         return file.exists();
        }
    
        /**
         * 预初始化模板文件<BR>
         * 当用户指定的模板文件不存在时,将自动生成指定的模板文件,并第一行设置为要导出的字段列
         * @param templateFile 模板文件名
         * @param dataObject 数据实体对象
         * @throws Exception
         */
        public void prepareInitializeTemplate(String templateFile,DataObject dataObject) throws Exception{
          HSSFWorkbook wb = new HSSFWorkbook();
          FileOutputStream fileOut = new FileOutputStream(templateFile);
          HSSFSheet sheet = wb.createSheet("new sheet");
          //设置模板的第一行为输出字段定义列
          HSSFRow row = sheet.createRow((short)0);
          Object[] properties=dataObject.getType().getDeclaredProperties().toArray();
          for(int i=0;i<properties.length;i++){
           PropertyImpl property=(PropertyImpl)properties[i];
           HSSFCell cell = row.createCell((short)i);
           HSSFRichTextString text=new HSSFRichTextString("#"+property.getName());
           cell.setCellValue(text);
          }
          wb.write(fileOut);
          fileOut.close();
        }
    }
    
  • com.primeton.example.excel.ExcelUtil:
    
    package com.primeton.example.excel;
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
     
    import com.eos.foundation.common.io.FileUtil;
    import com.eos.foundation.eoscommon.ConfigurationUtil;
    import com.eos.runtime.core.ApplicationContext;
    import com.eos.system.annotation.Bizlet;
    import com.eos.system.annotation.BizletParam;
    import com.eos.system.annotation.ParamType;
    import commonj.sdo.DataObject;
    /**
     *
     * Excel文件操作工具类<BR>
     *
     * @author primeton
     * wengzr (mailto:)
     */
    @Bizlet("Excel工具操作类")
    public class ExcelUtil {
     private ExcelUtil(){
      //工具类不允许实例化
     }
    
     /**
      * 将Excel数据导入到数据库指定的表,默认每500条数据执行一次批处理导入
      *
      * @param excelFile Excel文件名
      * @param entityFullName 导入的实体全名
      * @return
      * @throws Exception
      */
     @Bizlet(
      value="将Excel数据导入到数据库指定的表",
      params = {
       @BizletParam(index = 0, paramAlias = "excelFile",type=ParamType.CONSTANT),
             @BizletParam(index = 1, paramAlias = "entityFullName",type=ParamType.CONSTANT)
        }
     )
     public static int importExcel(String excelFile,String entityFullName)throws Exception{
      ExcelTemplate template=new ExcelTemplate();
      return template.importData(excelFile, entityFullName, 500);
     }
    
     /**
      * 将指定的对象数组exportObjects导出到指定模板的Excel文件
      *
      * @param exportObjects 待导出的对象数组
      * @param exportInfo  模板文件的其他附加信息(非结果集内容)
      * @param templateFilename 模板文件名(不带扩展名),对应到在user-config.xml配置路径下的模板文件
      * @return 返回生成的Excel文件下载路径
      * @throws Exception
      */
     @Bizlet(
      value="将指定的对象数组导出到指定模板的Excel文件",
      params = {
       @BizletParam(index = 0, paramAlias = "exportObjects",type=ParamType.VARIABLE),
             @BizletParam(index = 1, paramAlias = "exportInfo",type=ParamType.VARIABLE),
             @BizletParam(index = 2, paramAlias = "templateFilename",type=ParamType.CONSTANT)
         }
     )
     public static String exportExcel(DataObject[] exportObjects,DataObject exportInfo,String templateFilename) throws Exception{
      return exportExcel(exportObjects,exportInfo,templateFilename,false,false);
     }
     /**
      * 分页将对象数组导出到指定的模板Excel文件,注意:此时模板文件必需包含Excel表格的分页符
      * @param exportObjects 待导出的对象数组
      * @param exportInfo  模板文件的其他附加信息(非结果集内容)
      * @param templateFilename 模板文件名(不带扩展名),对应到在user-config.xml配置路径下的模板文件
      * @return 返回生成的Excel文件下载路径
      * @throws Exception
      */
     @Bizlet(
      value="分页将对象数组导出到指定的模板Excel文件",
      params = {
       @BizletParam(index = 0, paramAlias = "exportObjects",type=ParamType.VARIABLE),
             @BizletParam(index = 1, paramAlias = "exportInfo",type=ParamType.VARIABLE),
             @BizletParam(index = 2, paramAlias = "templateFilename",type=ParamType.CONSTANT)
         }
     )
     public static String exportExcelWithPagnation(DataObject[] exportObjects,DataObject exportInfo,String templateFilename)
    throws Exception{
      return exportExcel(exportObjects,exportInfo,templateFilename,true,false);
     }
     /**
      * 分工作表将对象数组导出到指定的模板Excel文件,默认情况下输出工作表最大行:20000
      * @param exportObjects 待导出的对象数组
      * @param exportInfo  模板文件的其他附加信息(非结果集内容)
      * @param templateFilename 模板文件名(不带扩展名),对应到在user-config.xml配置路径下的模板文件
      * @return 返回生成的Excel文件下载路径
      * @throws Exception
      */
     @Bizlet(
      value="分工作表将对象数组导出到指定的模板Excel文件",
      params = {
       @BizletParam(index = 0, paramAlias = "exportObjects",type=ParamType.VARIABLE),
             @BizletParam(index = 1, paramAlias = "exportInfo",type=ParamType.VARIABLE),
             @BizletParam(index = 2, paramAlias = "templateFilename",type=ParamType.CONSTANT)
         }
     )
     public static String exportExcelWithSheet(DataObject[] exportObjects,DataObject exportInfo,String templateFilename)
    throws Exception{
      return exportExcel(exportObjects,exportInfo,templateFilename,false,true);
     }
     /**
      * 导出Excel文件,根据指定路径下的模板生成输出的Excel文件
      *
      * @param exportObjects 待导出的对象数组
      * @param exportInfo 模板文件的其他附加信息(非结果集内容)
      * @param templateFilename 模板文件名(不带扩展名),对应到在user-config.xml配置路径下的模板文件
      * @param autoPagination 是否分页
      * @param autoSheet 是否分工作表
      * @return 返回生成的Excel文件下载路径
      * @throws Exception
      */
     private static String exportExcel(DataObject[] exportObjects,DataObject exportInfo,String templateFilename,
    boolean autoPagination,boolean autoSheet) throws Exception{
      String filename=templateFilename;
      if(filename.indexOf(".xls")==-1){
       filename+=".xls";
      }
      //临时路径是服务器当前war下面的excel-config目录
      String templateDir=ApplicationContext.getInstance().getWarRealPath()+ConfigurationUtil.getContributionConfig
    (UtilConfiguration.CONTRIBUTION_ABFRAME_UTILS,
        UtilConfiguration.MODULE_ABFRAME,
        UtilConfiguration.GROUP_EXCEL,
        UtilConfiguration.EXCEL_TEMPLATE_PATH);
      String excelExportMaxnum=ConfigurationUtil.getContributionConfig(UtilConfiguration.CONTRIBUTION_ABFRAME_UTILS,
        UtilConfiguration.MODULE_ABFRAME,
        UtilConfiguration.GROUP_EXCEL,
        UtilConfiguration.EXCEL_EXPORT_MAXNUM);
      
      if(!templateDir.endsWith("/")){
       templateDir+="/";
      }
      String tempDir=templateDir+"temp/";
      File file=new File(tempDir);
      if(!file.exists()){
       //创建临时目录
       FileUtil.mkDir(tempDir);
       //file.createNewFile();
      }
      String templateFile=templateDir+filename;
      String outputFile=tempDir+generateOutputExcelFile(filename);
      ExcelTemplate template=new ExcelTemplate(templateFile,outputFile);
      template.setAutoPagination(autoPagination);
      template.setAutoSheet(autoSheet);
      int excelExportMaxnumInt = 0;
      try{
       excelExportMaxnumInt = Integer.parseInt(excelExportMaxnum);
      }catch (Exception e){
       e.printStackTrace();
      }
      template.setMaxRow(excelExportMaxnumInt);
      template.generate(Arrays.asList(exportObjects),exportInfo);
      return outputFile;
     }
     /**
      * 生成EXCEL输出文件,默认带时间戳
      * @param templateFilename 文件名
      * @return
      */
     private static String generateOutputExcelFile(String templateFilename){
      String filename=templateFilename;
      if(templateFilename.endsWith(".xls")){
       filename=templateFilename.substring(0,templateFilename.length()-4);
      }
      SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss");
      String datetimeString=format.format(new Date());
      filename=filename+"_"+datetimeString+".xls";
      return filename;
     }
    }
    
  • com.primeton.example.excel.UtilConfiguration:
    /*******************************************************************************
     * $Header: /opt/cvsroot/wiki/opensource/gocom/abframe2/src/
    org.gocom.abframe.tools/src/org/gocom/abframe/tools/UtilConfiguration.java,
    v 1.3 2009/03/30 05:39:38 caisy Exp $
     * $Revision: 1.3 $
     * $Date: 2009/03/30 05:39:38 $
     *
     *==============================================================================
     *
     * Copyright (c) 2001-2006 Primeton Technologies, Ltd.
     * All rights reserved.
     *
     * Created on 2008-9-17
     *******************************************************************************/
    package com.primeton.example.excel;
    /**
     *
     * Utility构件包配置常量定义
     *
     * @author primeton
     * wengzr (mailto:)
     */
    public interface UtilConfiguration {
     public static final String CONTRIBUTION_ABFRAME_UTILS="com.primeton.example.excel";
     public static final String MODULE_ABFRAME="example-config";
     public static final String GROUP_EXCEL="excel-config";
     /**
      * EXCEL模板路径
      */
     public static final String EXCEL_TEMPLATE_PATH="excel_template_path";
     
     /**
      * 导出EXCEL最大行数
      */
     public static final String EXCEL_EXPORT_MAXNUM="excel_export_maxnum";
    
    }
    

步骤4:逻辑流开发

  1. 逻辑流"导入数据到EXAMPLE_EMP表"importExcelWithDictEntry开发,效果如下:
    1. 逻辑流importExcelWithDictEntry的参数配置如下:
      类型名称类型数组描述
      参数excelFileString 上传后的Excel文件名
      返回值reCodeString 返回下载文件路径
    2. 运算逻辑"com.primeton.sample.ExcelUtil.importExcel",描述为"导入EXAMPLE_EMP表",其参数如下:
      类型名称右值类别赋值方式
      参数excelFileexcelFile变量传引用
      参数entituFullNamecom.primeton.sample.sampledataset.ExampleEmp常量传引用
      返回值out0result变量传引用
    3. "成功返回1"属性设置:
      序号左值右值右值类别赋值方式
      1retCode1常量传引用
    4. "失败返回"属性设置:
      序号左值右值右值类别赋值方式
      1retCode0常量传引用
  2. 逻辑流"导出Excel"exportEmpExcel开发,效果如下:
    1. 逻辑流exportEmpExcel的参数配置如下:
      类型名称类型数组描述
      返回值downloadFileString 返回下载文件路径

      变量定义如下:

      名称类型数组参数描述
      criteriacriteriaType 
    2. "查询条件赋值"属性设置:
      序号左值右值右值类别赋值方式
      1criteria/_entitycom.primeton.example.excel.sampledataset.ExampleEmp常量传引用
    3. 运算逻辑"查询导出Excel数据集"queryEntitiesByCriteriaEntity,其参数如下:
      类型名称数据类型值类别传递方式
      参数dsNameStingdefault常量传引用
      参数criteriaEntityDataObjectcriteria变量传引用
      返回值out0DataObject[]empList变量传引用
    4. 运算逻辑"导出Excel"exportExcel,其参数如下:
      类型名称数据类型值类别传递方式
      参数exportObjectsDataObject[]empList变量传引用
      参数exportInfoDataObjectnull表达式传引用
      参数templateFilenameStringEmpTemplate常量传引用
      返回值out0String[]downloadFile变量传引用

步骤5:页面开发

  1. 员工信息导入导出页面emp_manager.jsp:
    <%@page pageEncoding="UTF-8"%>
    <%@include file="/common.jsp"%>
    <html>
    <!--
      - Author(s): chenfeng
      - Date: 2009-06-08 11:40:08
      - Description:
    -->
    <head>
    <title>企业员工导入导出</title>
    </head>
    <body>
     
    <table align="center" border="0" width="100%" class="form_table">
      <tr>
       <td  colSpan="4" class="eos-panel-title">
          员工信息Excel文件导入
       </td>
      </tr>
      <h:form id="importForm" action="com.primeton.example.excel.empManager.flow" method="post" enctype="multipart/form-data" >
      <tr>
       <td class="form_label" align="center" width="30%">
         员工信息Excel文件:
       </td>
       <td class="form_label" style="text-align: left;">
        <input type="file" name="empItemFile" size="60">
       </td>
      </tr>
      <tr>
       <td colSpan="4" align="center">
           <input type="button" value="导出员工信息" οnclick="exportEmp();"/><!-- 导出 -->
        <input type="button" value='导入员工信息' οnclick="empImport();"/><!-- 导入 -->
        <input type="reset"" value='重置' /><!-- 重置 -->
        
       </td>
       </tr>
      </h:form>
     </table>
    <h:form id="queryForm">
    </h:form>            
    </body>
    <script language="javascript">
      /*
      * 功能:从EXAMPLE_EMP表导出信息成excel
      */
        function exportEmp()
        {
         var frm = $id("queryForm");
         frm.action = "com.primeton.example.excel.empManager.flow?_eosFlowAction=exportFile";
         frm.submit();
        }
     
      /*
      * 功能:导入EXAMPLE_EMP表内
      */
     function empImport(){
      var frm = $id("importForm");
      var excelFile = $name("empItemFile").value;
      if (excelFile=="") {
       alert('请选择您要导入的Excel文件!');//请选择您要导入的Excel文件!
       return;
      }
      var re= /.xls$/;
      if (!re.test(excelFile))
      {
       alert('请选择Excel文件!'); //请选择Excel文件!
       return;
      }
      excelFile = excelFile.substr(excelFile.lastIndexOf("\\") + 1);
      frm.action = "com.primeton.example.excel.empManager.flow?_eosFlowAction=importFile&excelFile=" + excelFile;
      frm.submit();
     }
     
    </script>
    </html>
    
  2. download.jsp:
    <%@page pageEncoding="UTF-8"%>
    <%@page import="javax.servlet.ServletOutputStream"%>
    <%@page import="java.io.*"%>
    <%@page import="com.eos.web.taglib.util.*" %><%
       //获取标签中使用的国际化资源信息
       String fileNotExist=com.eos.foundation.eoscommon.ResourcesMessageUtil.getI18nResourceMessage("l_fileNotExist");
          Object root= com.eos.web.taglib.util.XpathUtil.getDataContextRoot("request", pageContext);
          String localFile=(String)XpathUtil.getObjectByXpath(root,"downloadFile");
       
          System.out.println(">>>>download file is "+localFile);
       byte[] buffer = new byte[512];
       int size = 0;
       response.reset();
       response.setContentType("application/vnd.ms-excel");
        //response.setHeader("Content-disposition", "attachment;filename=\""+ java.net.URLEncoder.encode(localFile,"UTF-8") + "\"");
        response.setHeader("Content-disposition", "attachment;filename=\""+ java.net.URLEncoder.encode("tempExcel.xls","UTF-8") + "\"");
       ServletOutputStream os = null;
       FileInputStream in = null;
       try {
          os = response.getOutputStream();
          File downloadFile=new File(localFile);
          if(downloadFile!=null&&downloadFile.exists()){
           in = new FileInputStream(new File(localFile));
           while ((size = in.read(buffer)) != -1) {
             os.write(buffer, 0, size);
           }
          out.clear();
              out = pageContext.pushBody();
          }else{
             out.print(fileNotExist); //"文件不存在!"
          }
          } catch(Exception e) {
              e.printStackTrace();
           } finally {
                try {
                 if(in!=null)in.close();
           if(os!=null)os.close();
           File file=new File(localFile);
           if (file!=null&&file.isFile()&&file.exists()) {
             file.delete();
           }
         } catch (IOException e) {
           e.printStackTrace();
         }
           }
    %>
    

步骤6:页面流开发
在右边的页面流编辑器中拖入emp_manager.jsp,命名为"员工信息导入导出";
拖入逻辑流com.primeton.example.excel.export.exportEmpExcel,命名为"导出Excel";
拖入逻辑流importExcelWithDictEntry,命名为"导入数据到EXAMPLE_EMP表";
拖入download.jsp,再用连接线相连,如下所示:

"员工数据导入导出"与"导出Excel"相连的连接线ActionName=exportFile且输出参数为:

名称数据类型数组参数描述
pagePageCond 分页
dictTypecriteriaType 查询条件


"员工数据导入导出"与"导入数据到EXAMPLE_EMP表"相连的连接线ActionName=importFile且输出参数为:

名称数据类型数组参数描述
empItemFile上传文件类型  


"导出Excel"的参数配置为:

类型名称数据类型值类别传递方式
参数downloadFileStringdownloadFile变量传引用


"导入数据到EXAMPLE_EMP表"参数配置:

类型名称数据类型值类别传递方式
参数excelFileStringempItemFile/filePath变量传引用
返回值retCodeStringretCode变量传引用

步骤7:配置Excel模板
在构件包配置文件 contribution.eosinf中增加excel模板的配置:

<!-- 相关配置 -->
    <module name="example-config">
        <!-- Excel相关配置 -->
        <group name="excel-config">
        	<!-- EXCEL模板路径 -->
            <configValue key="excel_template_path">/WEB-INF/excel-config/</configValue>
            <!-- 导出EXCEL最大行数 -->
            <configValue key="excel_export_maxnum">10000</configValue>
        </group>
    </module>

部署和运行

  1. 在构件包的右键菜单中,选择"部署";
  2. 以"调试方式"启动Server。
    在浏览器中输入如下地址:http://127.0.0.1:8080/eos-default/com.primeton.example.excel.empManager.flow


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值