|
注意 导入文件的内容数据格式如下,第一行指定字段名,需要用字段#开始,第二行是中文字段标识,第三行以后才是数据。例如:
|
开发步骤
步骤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文档中的" "为" ", "<"为"<", ">"为">","<br>"为"\r\n" * * @param _rawStr 原始Html文档 * @return 替换后的Html文档 */ public static String changeHtmlStr(String _rawStr) { String str = null; if (_rawStr != null) { str = replaceString( " ", " ", _rawStr); str = replaceString( "<","<", str); str = replaceString( ">",">", str); str = replaceString( "&","&", str); str = replaceString( ""","\"", 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:逻辑流开发
- 逻辑流"导入数据到EXAMPLE_EMP表"importExcelWithDictEntry开发,效果如下:
- 逻辑流importExcelWithDictEntry的参数配置如下:
类型 名称 类型 数组 描述 参数 excelFile String 上传后的Excel文件名 返回值 reCode String 返回下载文件路径 - 运算逻辑"com.primeton.sample.ExcelUtil.importExcel",描述为"导入EXAMPLE_EMP表",其参数如下:
类型 名称 值 右值类别 赋值方式 参数 excelFile excelFile 变量 传引用 参数 entituFullName com.primeton.sample.sampledataset.ExampleEmp 常量 传引用 返回值 out0 result 变量 传引用 - "成功返回1"属性设置:
序号 左值 右值 右值类别 赋值方式 1 retCode 1 常量 传引用 - "失败返回"属性设置:
序号 左值 右值 右值类别 赋值方式 1 retCode 0 常量 传引用
- 逻辑流importExcelWithDictEntry的参数配置如下:
- 逻辑流"导出Excel"exportEmpExcel开发,效果如下:
- 逻辑流exportEmpExcel的参数配置如下:
类型 名称 类型 数组 描述 返回值 downloadFile String 返回下载文件路径 变量定义如下:
名称 类型 数组 参数描述 criteria criteriaType 否 - "查询条件赋值"属性设置:
序号 左值 右值 右值类别 赋值方式 1 criteria/_entity com.primeton.example.excel.sampledataset.ExampleEmp 常量 传引用 - 运算逻辑"查询导出Excel数据集"queryEntitiesByCriteriaEntity,其参数如下:
类型 名称 数据类型 值 值类别 传递方式 参数 dsName Sting default 常量 传引用 参数 criteriaEntity DataObject criteria 变量 传引用 返回值 out0 DataObject[] empList 变量 传引用 - 运算逻辑"导出Excel"exportExcel,其参数如下:
类型 名称 数据类型 值 值类别 传递方式 参数 exportObjects DataObject[] empList 变量 传引用 参数 exportInfo DataObject null 表达式 传引用 参数 templateFilename String EmpTemplate 常量 传引用 返回值 out0 String[] downloadFile 变量 传引用
- 逻辑流exportEmpExcel的参数配置如下:
步骤5:页面开发
- 员工信息导入导出页面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>
- 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且输出参数为:
名称 | 数据类型 | 数组 | 参数描述 |
---|---|---|---|
page | PageCond | 分页 | |
dictType | criteriaType | 查询条件 |
"员工数据导入导出"与"导入数据到EXAMPLE_EMP表"相连的连接线ActionName=importFile且输出参数为:
名称 | 数据类型 | 数组 | 参数描述 |
---|---|---|---|
empItemFile | 上传文件类型 |
"导出Excel"的参数配置为:
类型 | 名称 | 数据类型 | 值 | 值类别 | 传递方式 |
---|---|---|---|---|---|
参数 | downloadFile | String | downloadFile | 变量 | 传引用 |
"导入数据到EXAMPLE_EMP表"参数配置:
类型 | 名称 | 数据类型 | 值 | 值类别 | 传递方式 |
---|---|---|---|---|---|
参数 | excelFile | String | empItemFile/filePath | 变量 | 传引用 |
返回值 | retCode | String | retCode | 变量 | 传引用 |
步骤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>
部署和运行
- 在构件包的右键菜单中,选择"部署";
- 以"调试方式"启动Server。
在浏览器中输入如下地址:http://127.0.0.1:8080/eos-default/com.primeton.example.excel.empManager.flow