场景描述

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

场景目标

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

页面效果

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

注意
导入文件的内容数据格式如下,第一行指定字段名,需要用字段#开始,第二行是中文字段标识,第三行以后才是数据。例如:

#empid #orgid #empcode #empname #sex #birthday #postcode #address #phone #wage
员工id 机构代码 员工代码 姓名 性别 生日 邮编 地址 电话 薪资
2 1 2 张无忌 M 1972-11-30 710071 上海张江高科技园区碧波路456号4层 80080002 2000
3 1 3 张小宝 M 1974-5-19 710072 北京市海淀区彩和坊路8号天创科技大厦东门1301室 80080003 2000
4 1 4 赵大海 M 1977-7-8 710073 广州市天河区体育东路 80080004 2000

开发步骤

步骤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);elsech = "" + (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的参数配置如下:

      类型 名称 类型 数组 描述
      参数 excelFile String   上传后的Excel文件名
      返回值 reCode String   返回下载文件路径
    2. 运算逻辑"com.primeton.sample.ExcelUtil.importExcel",描述为"导入EXAMPLE_EMP表",其参数如下:
      类型 名称 右值类别 赋值方式
      参数 excelFile excelFile 变量 传引用
      参数 entituFullName com.primeton.sample.sampledataset.ExampleEmp 常量 传引用
      返回值 out0 result 变量 传引用
    3. "成功返回1"属性设置:
      序号 左值 右值 右值类别 赋值方式
      1 retCode 1 常量 传引用
    4. "失败返回"属性设置:
      序号 左值 右值 右值类别 赋值方式
      1 retCode 0 常量 传引用
  2. 逻辑流"导出Excel"exportEmpExcel开发,效果如下:

    1. 逻辑流exportEmpExcel的参数配置如下:

      类型 名称 类型 数组 描述
      返回值 downloadFile String   返回下载文件路径

      变量定义如下:

      名称 类型 数组 参数描述
      criteria criteriaType  
    2. "查询条件赋值"属性设置:
      序号 左值 右值 右值类别 赋值方式
      1 criteria/_entity com.primeton.example.excel.sampledataset.ExampleEmp 常量 传引用
    3. 运算逻辑"查询导出Excel数据集"queryEntitiesByCriteriaEntity,其参数如下:
      类型 名称 数据类型 值类别 传递方式
      参数 dsName Sting default 常量 传引用
      参数 criteriaEntity DataObject criteria 变量 传引用
      返回值 out0 DataObject[] empList 变量 传引用
    4. 运算逻辑"导出Excel"exportExcel,其参数如下:
      类型 名称 数据类型 值类别 传递方式
      参数 exportObjects DataObject[] empList 变量 传引用
      参数 exportInfo DataObject null 表达式 传引用
      参数 templateFilename String EmpTemplate 常量 传引用
      返回值 out0 String[] 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且输出参数为:

名称 数据类型 数组 参数描述
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>

部署和运行

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

导入导出excel文件相关推荐

  1. 【转】 (C#)利用Aspose.Cells组件导入导出excel文件

    Aspose.Cells组件可以不依赖excel来导入导出excel文件: 导入: public static System.Data.DataTable ReadExcel(String strFi ...

  2. java导入导出excel文件

    前言:该文章使用java集成poi来操作excel文件,此处只对poi相关api进行代码编写,对于poi的理论性知识,可在学习完这篇文章后,自行百度学习.建议大家跟着文章敲一遍代码. 创建一个mave ...

  3. EOS中如何实现导入导出excel文件

    阅读原文 导入导出excel文件 场景描述 将数据库表中的数据按照定义的EXCEL模板进行导出,下载到本地: 将EXCEL中的数据导入数据库相应的表中. 场景目标 通过本场景,解决EXCEL的导入导出 ...

  4. 批量导入/导出Excel文件(Python+Matlab)

    简单整理了下批量导入/导出Excel的Python和Matlab代码. Matlab 连续数字型.xlsx文件(如file_1.xlsx, file_2.xlsx, file_3.xlsx) clc, ...

  5. mediawiki 导入导出Excel文件

     导入导出Excel表格需要使用插件Data_Transfer Data Transfer is an extension to MediaWiki that allows users to bo ...

  6. SpringBoot使用poi或EasyExcel导入导出Excel文件

    使用poi导入导出Excel 首先引入poi依赖包 03版本的Excel和07版本的Excel所需要的依赖不同,都需要导入. 记录问题: 最初导入的poi包为3.6版本.WorkBook类和Sheet ...

  7. EasyExcel 导入导出Excel文件

    文章目录 写在前面 1.maven依赖 2.导入Excel文件 2.1.读取表格文件 2.2.如果有多个sheet表格 2.3.监听器封装(也可不封装) 2.4.读取数据格式化(实体类中添加注解) 3 ...

  8. java excel jxls_java通过jxls框架实现导入导出excel文件实例

    //使用jxls报表生成工具,把java实体类导出生成 Excel文件或导入 Excel 插入数据库 //读取 public class ReadExcel { private final stati ...

  9. c++_导入/导出excel文件

    2019独角兽企业重金招聘Python工程师标准>>> 方法1:通过数据库 (1)导出excel CDatabase database; CString sDriver = _T(& ...

最新文章

  1. New Phytologist:生态中心张丽梅组-宿主选择效应塑造作物微生物组群落构建及网络复杂度...
  2. 7-9将灰度转为彩色
  3. MOSS站点的FORM认证修改小结
  4. 本地搭建wp,更新升级时需要ftp的解决办法
  5. 【转载】使用tf.py_func函数增加Tensorflow程序的灵活性
  6. NVolecity 处理DataTable 小记
  7. 逻辑删除用户后 用户名重复怎么办?
  8. 巧解汽车冬季病 启动无力别“轰油”热车
  9. C++基础——类继承中方法重载
  10. 服务器虚拟化底层实现原理,虚拟化原理
  11. ftp服务器支持ipv6,IPV6下搭建FTP服务器的步骤
  12. element ui 手动清除表单效验提示语
  13. 百度分享如何自定义分享url和内容?
  14. 原来,嵌入式BI方案的核心差异在这,教你如何评估
  15. MongoDB 4.2.3 安装以及安装遇到的问题“service MongoDB failed to start,verify that you have sufficient privilege”
  16. matplotlib自定义设置plt.colorbar函数配置颜色条的刻度数实战:自定义设置颜色条刻度、并为刻度值进行命名和标签化
  17. 推荐系统中的pointwise和pairwise区别
  18. 非计算机专业跨计算机,非计算机专业跨考考研计算机难度如何?
  19. 使用Python实现网格索引
  20. OA 下载 sliverlight 网站

热门文章

  1. Halo博客的谷歌收录自动提交
  2. Oracle 9i,10g/11g,12c中的i,g,c分别代表什么含义
  3. 如何单独编译Android源代码中的模块
  4. Visual Studio 2019调试HTK代码
  5. JavaWeb_script
  6. 6-6 实验6_9_素数分解 (100分)
  7. r6220 虚拟服务器,网件r6220设置页面打不开 其实很简单
  8. cvs100e_施耐德塑壳断路器CVS100ETMD3P100
  9. 安装python包时报‘HTMLParser‘ object has no attribute ‘unescape‘
  10. mod python中文文档_mod_python中文文档