阅读原文
导入导出excel文件
场景描述
将数据库表中的数据按照定义的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:
/*******************************************************************************
* $Header: /opt/cvsroot/wiki/opensource/gocom/abframe2/src/
org.gocom.abframe.tools/src/org/gocom/abframe/tools/ChangeUtil.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-3
*******************************************************************************/
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:
/*******************************************************************************
* $Header: /opt/cvsroot/wiki/opensource/gocom/abframe2/src/org.gocom.abframe.tools/
src/org/gocom/abframe/tools/ExcelTemplate.java,v 1.6 2009/03/30 05:39:38 caisy Exp $
* $Revision: 1.6 $
* $Date: 2009/03/30 05:39:38 $
*
*==============================================================================
*
* Copyright (c) 2001-2006 Primeton Technologies, Ltd.
* All rights reserved.
*
* Created on 2008-9-3
*******************************************************************************/
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:
/*******************************************************************************
* $Header: /opt/cvsroot/wiki/opensource/gocom/abframe2/src/org.gocom.abframe.tools/
src/org/gocom/abframe/tools/ExcelUtil.java,v 1.5 2009/03/30 05:39:38 caisy Exp $
* $Revision: 1.5 $
* $Date: 2009/03/30 05:39:38 $
*
*==============================================================================
*
* Copyright (c) 2001-2006 Primeton Technologies, Ltd.
* All rights reserved.
*
* Created on 2008-9-3
*******************************************************************************/
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=
"导出员工信息"
onclick=
"exportEmp();"
/><!-- 导出 -->
<input type=
"button"
value=
'导入员工信息'
onclick=
"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