Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fgqyxxlr
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
yaru
fgqyxxlr
Commits
ec8c7f1d
Commit
ec8c7f1d
authored
Jan 10, 2019
by
RuoYi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持用户数据导入
parent
619e1d24
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1046 additions
and
209 deletions
+1046
-209
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobLogController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
+1
-1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
+24
-2
ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css
+44
-9
ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js
+63
-1
ruoyi-admin/src/main/resources/templates/system/user/edit.html
+1
-1
ruoyi-admin/src/main/resources/templates/system/user/user.html
+19
-0
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java
+23
-1
ruoyi-common/src/main/java/com/ruoyi/common/reflect/ReflectUtils.java
+406
-0
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelUtil.java
+350
-164
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java
+5
-0
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
+8
-0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
+94
-22
No files found.
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobController.java
View file @
ec8c7f1d
...
...
@@ -59,7 +59,7 @@ public class SysJobController extends BaseController
{
List
<
SysJob
>
list
=
jobService
.
selectJobList
(
job
);
ExcelUtil
<
SysJob
>
util
=
new
ExcelUtil
<
SysJob
>(
SysJob
.
class
);
return
util
.
exportExcel
(
list
,
"
job
"
);
return
util
.
exportExcel
(
list
,
"
定时任务
"
);
}
@Log
(
title
=
"定时任务"
,
businessType
=
BusinessType
.
DELETE
)
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobLogController.java
View file @
ec8c7f1d
...
...
@@ -58,7 +58,7 @@ public class SysJobLogController extends BaseController
{
List
<
SysJobLog
>
list
=
jobLogService
.
selectJobLogList
(
jobLog
);
ExcelUtil
<
SysJobLog
>
util
=
new
ExcelUtil
<
SysJobLog
>(
SysJobLog
.
class
);
return
util
.
exportExcel
(
list
,
"
jobLog
"
);
return
util
.
exportExcel
(
list
,
"
调度日志
"
);
}
@Log
(
title
=
"调度日志"
,
businessType
=
BusinessType
.
DELETE
)
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java
View file @
ec8c7f1d
...
...
@@ -56,7 +56,7 @@ public class SysLogininforController extends BaseController
{
List
<
SysLogininfor
>
list
=
logininforService
.
selectLogininforList
(
logininfor
);
ExcelUtil
<
SysLogininfor
>
util
=
new
ExcelUtil
<
SysLogininfor
>(
SysLogininfor
.
class
);
return
util
.
exportExcel
(
list
,
"
logininfor
"
);
return
util
.
exportExcel
(
list
,
"
登陆日志
"
);
}
@RequiresPermissions
(
"monitor:logininfor:remove"
)
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java
View file @
ec8c7f1d
...
...
@@ -58,7 +58,7 @@ public class SysOperlogController extends BaseController
{
List
<
SysOperLog
>
list
=
operLogService
.
selectOperLogList
(
operLog
);
ExcelUtil
<
SysOperLog
>
util
=
new
ExcelUtil
<
SysOperLog
>(
SysOperLog
.
class
);
return
util
.
exportExcel
(
list
,
"
operLog
"
);
return
util
.
exportExcel
(
list
,
"
操作日志
"
);
}
@RequiresPermissions
(
"monitor:operlog:remove"
)
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
View file @
ec8c7f1d
...
...
@@ -62,7 +62,7 @@ public class SysConfigController extends BaseController
{
List
<
SysConfig
>
list
=
configService
.
selectConfigList
(
config
);
ExcelUtil
<
SysConfig
>
util
=
new
ExcelUtil
<
SysConfig
>(
SysConfig
.
class
);
return
util
.
exportExcel
(
list
,
"
config
"
);
return
util
.
exportExcel
(
list
,
"
参数数据
"
);
}
/**
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
View file @
ec8c7f1d
...
...
@@ -59,7 +59,7 @@ public class SysDictDataController extends BaseController
{
List
<
SysDictData
>
list
=
dictDataService
.
selectDictDataList
(
dictData
);
ExcelUtil
<
SysDictData
>
util
=
new
ExcelUtil
<
SysDictData
>(
SysDictData
.
class
);
return
util
.
exportExcel
(
list
,
"
dictData
"
);
return
util
.
exportExcel
(
list
,
"
字典数据
"
);
}
/**
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
View file @
ec8c7f1d
...
...
@@ -60,7 +60,7 @@ public class SysDictTypeController extends BaseController
List
<
SysDictType
>
list
=
dictTypeService
.
selectDictTypeList
(
dictType
);
ExcelUtil
<
SysDictType
>
util
=
new
ExcelUtil
<
SysDictType
>(
SysDictType
.
class
);
return
util
.
exportExcel
(
list
,
"
dictType
"
);
return
util
.
exportExcel
(
list
,
"
字典类型
"
);
}
/**
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java
View file @
ec8c7f1d
...
...
@@ -59,7 +59,7 @@ public class SysPostController extends BaseController
{
List
<
SysPost
>
list
=
postService
.
selectPostList
(
post
);
ExcelUtil
<
SysPost
>
util
=
new
ExcelUtil
<
SysPost
>(
SysPost
.
class
);
return
util
.
exportExcel
(
list
,
"
post
"
);
return
util
.
exportExcel
(
list
,
"
岗位数据
"
);
}
@RequiresPermissions
(
"system:post:remove"
)
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java
View file @
ec8c7f1d
...
...
@@ -60,7 +60,7 @@ public class SysRoleController extends BaseController
{
List
<
SysRole
>
list
=
roleService
.
selectRoleList
(
role
);
ExcelUtil
<
SysRole
>
util
=
new
ExcelUtil
<
SysRole
>(
SysRole
.
class
);
return
util
.
exportExcel
(
list
,
"
role
"
);
return
util
.
exportExcel
(
list
,
"
角色数据
"
);
}
/**
...
...
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
View file @
ec8c7f1d
...
...
@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.multipart.MultipartFile
;
import
com.ruoyi.common.annotation.Log
;
import
com.ruoyi.common.base.AjaxResult
;
import
com.ruoyi.common.enums.BusinessType
;
...
...
@@ -19,11 +20,11 @@ import com.ruoyi.common.utils.ExcelUtil;
import
com.ruoyi.common.utils.StringUtils
;
import
com.ruoyi.framework.shiro.service.SysPasswordService
;
import
com.ruoyi.framework.util.ShiroUtils
;
import
com.ruoyi.framework.web.base.BaseController
;
import
com.ruoyi.system.domain.SysUser
;
import
com.ruoyi.system.service.ISysPostService
;
import
com.ruoyi.system.service.ISysRoleService
;
import
com.ruoyi.system.service.ISysUserService
;
import
com.ruoyi.framework.web.base.BaseController
;
/**
* 用户信息
...
...
@@ -73,7 +74,28 @@ public class SysUserController extends BaseController
{
List
<
SysUser
>
list
=
userService
.
selectUserList
(
user
);
ExcelUtil
<
SysUser
>
util
=
new
ExcelUtil
<
SysUser
>(
SysUser
.
class
);
return
util
.
exportExcel
(
list
,
"user"
);
return
util
.
exportExcel
(
list
,
"用户数据"
);
}
@Log
(
title
=
"用户管理"
,
businessType
=
BusinessType
.
IMPORT
)
@RequiresPermissions
(
"system:user:import"
)
@PostMapping
(
"/importData"
)
@ResponseBody
public
AjaxResult
importData
(
MultipartFile
file
,
boolean
updateSupport
)
throws
Exception
{
ExcelUtil
<
SysUser
>
util
=
new
ExcelUtil
<
SysUser
>(
SysUser
.
class
);
List
<
SysUser
>
userList
=
util
.
importExcel
(
file
.
getInputStream
());
String
message
=
userService
.
importUser
(
userList
,
updateSupport
);
return
AjaxResult
.
success
(
message
);
}
@RequiresPermissions
(
"system:user:view"
)
@GetMapping
(
"/importTemplate"
)
@ResponseBody
public
AjaxResult
importTemplate
()
{
ExcelUtil
<
SysUser
>
util
=
new
ExcelUtil
<
SysUser
>(
SysUser
.
class
);
return
util
.
importTemplateExcel
(
"用户数据"
);
}
/**
...
...
ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css
View file @
ec8c7f1d
...
...
@@ -3,7 +3,42 @@
* Copyright (c) 2018 ruoyi
*/
/** 用户管理 样式布局 */
/** 基础通用 **/
.pt5
{
padding-top
:
5px
;
}
.pr5
{
padding-right
:
5px
;
}
.pb5
{
padding-bottom
:
5px
;
}
.mt10
{
margin-top
:
10px
;
}
.mr10
{
margin-right
:
10px
;
}
.mb10
{
margin-bottom
:
10px
;
}
.ml0
{
margin-left
:
10px
;
}
.mt20
{
margin-top
:
20px
;
}
.mr20
{
margin-right
:
20px
;
}
.mb20
{
margin-bottom
:
20px
;
}
.ml20
{
margin-left
:
20px
;
}
/** 用户管理 样式布局 **/
.box
{
position
:
relative
;
border-radius
:
3px
;
...
...
@@ -91,7 +126,7 @@
margin
:
5px
0
5px
-25px
}
/** select2 样式修改 */
/** select2 样式修改 *
*
/
.select2-container--default
.select2-selection--multiple
.select2-selection__choice
{
background-color
:
#1AB394
;
border-color
:
#1AB394
;
...
...
@@ -112,7 +147,7 @@
padding-right
:
10px
}
/** 表单验证 样式布局 */
/** 表单验证 样式布局 *
*
/
label
.error
{
position
:
absolute
;
right
:
18px
;
...
...
@@ -143,7 +178,7 @@ label.error {
max-width
:
none
;
}
/** 复选框&单选框 */
/** 复选框&单选框 *
*
/
.check-box
,
.radio-box
{
display
:
inline-block
;
box-sizing
:
border-box
;
...
...
@@ -160,7 +195,7 @@ label.error {
left
:
0
}
/*
iCheck
*/
/*
* iCheck *
*/
.icheckbox-blue
,
.iradio-blue
{
display
:
block
;
margin
:
0
;
...
...
@@ -214,7 +249,7 @@ label.error {
background-position
:
-180px
0
}
/** 遮罩层 */
/** 遮罩层 *
*
/
.loaderbox
{
display
:
inline-block
;
min-width
:
125px
;
...
...
@@ -281,7 +316,7 @@ label.error {
}
}
/** 表单查询条件 */
/** 表单查询条件 *
*
/
ul
{
margin
:
0
;
padding
:
0
;
...
...
@@ -409,7 +444,7 @@ label {
cursor
:
pointer
;
}
/** 表格查询数据 */
/** 表格查询数据 *
*
/
.table-striped
{
min-height
:
75%
;
}
...
...
@@ -437,7 +472,7 @@ label {
border
:
1px
solid
#ddd
!important
}
/** 首页样式 */
/** 首页样式 *
*
/
.ax_close_max
{
position
:
fixed
;
top
:
5px
;
...
...
ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js
View file @
ec8c7f1d
...
...
@@ -92,7 +92,7 @@
}
$
(
"#bootstrap-table"
).
bootstrapTable
(
'refresh'
,
params
);
},
//
下载-默认第一个form
//
导出数据
exportExcel
:
function
(
formId
)
{
var
currentId
=
$
.
common
.
isEmpty
(
formId
)
?
$
(
'form'
).
attr
(
'id'
)
:
formId
;
$
.
modal
.
loading
(
"正在导出数据,请稍后..."
);
...
...
@@ -105,6 +105,64 @@
$
.
modal
.
closeLoading
();
});
},
// 下载模板
importTemplate
:
function
()
{
$
.
get
(
$
.
table
.
_option
.
importTemplateUrl
,
function
(
result
)
{
if
(
result
.
code
==
web_status
.
SUCCESS
)
{
window
.
location
.
href
=
ctx
+
"common/download?fileName="
+
result
.
msg
+
"&delete="
+
true
;
}
else
{
$
.
modal
.
alertError
(
result
.
msg
);
}
});
},
// 导入数据
importExcel
:
function
(
formId
)
{
var
currentId
=
$
.
common
.
isEmpty
(
formId
)
?
'importForm'
:
formId
;
$
.
form
.
reset
(
currentId
);
layer
.
open
({
type
:
1
,
area
:
[
'400px'
],
fix
:
false
,
//不固定
maxmin
:
true
,
shade
:
0.3
,
title
:
'导入'
+
$
.
table
.
_option
.
modalName
+
'数据'
,
content
:
$
(
'#'
+
currentId
),
btn
:
[
'<i class="fa fa-check"></i> 导入'
,
'<i class="fa fa-remove"></i> 取消'
],
// 弹层外区域关闭
shadeClose
:
true
,
btn1
:
function
(
index
,
layero
){
var
file
=
layero
.
find
(
'#file'
).
val
();
if
(
file
==
''
||
(
!
$
.
common
.
endWith
(
file
,
'.xls'
)
&&
!
$
.
common
.
endWith
(
file
,
'.xlsx'
))){
$
.
modal
.
msgWarning
(
"请选择后缀为 “xls”或“xlsx”的文件。"
);
return
false
;
}
var
index
=
layer
.
load
(
2
,
{
shade
:
false
});
var
url
=
prefix
+
"/importData"
;
var
formData
=
new
FormData
();
formData
.
append
(
"file"
,
$
(
'#file'
)[
0
].
files
[
0
]);
formData
.
append
(
"updateSupport"
,
$
(
"input[name='updateSupport']"
).
is
(
':checked'
));
$
.
ajax
({
url
:
url
,
data
:
formData
,
cache
:
false
,
contentType
:
false
,
processData
:
false
,
type
:
'POST'
,
success
:
function
(
result
)
{
if
(
result
.
code
==
web_status
.
SUCCESS
)
{
$
.
modal
.
closeAll
();
$
.
modal
.
alertSuccess
(
result
.
msg
);
$
.
table
.
refresh
();
}
else
{
layer
.
close
(
index
);
$
.
modal
.
alertError
(
result
.
msg
);
}
}
});
}
});
},
// 刷新表格
refresh
:
function
()
{
$
(
"#bootstrap-table"
).
bootstrapTable
(
'refresh'
,
{
...
...
@@ -288,6 +346,10 @@
var
index
=
parent
.
layer
.
getFrameIndex
(
window
.
name
);
parent
.
layer
.
close
(
index
);
},
// 关闭全部窗体
closeAll
:
function
()
{
layer
.
closeAll
();
},
// 确认窗体
confirm
:
function
(
content
,
callBack
)
{
layer
.
confirm
(
content
,
{
...
...
ruoyi-admin/src/main/resources/templates/system/user/edit.html
View file @
ec8c7f1d
...
...
@@ -184,7 +184,7 @@
/*用户管理-修改-选择部门树*/
function
selectDeptTree
()
{
var
deptId
=
$
(
"#treeId"
).
val
();
var
deptId
=
$
.
common
.
isEmpty
(
$
(
"#treeId"
).
val
())
?
"100"
:
$
(
"#treeId"
).
val
();
var
url
=
ctx
+
"system/dept/selectDeptTree/"
+
deptId
;
var
options
=
{
title
:
'选择部门'
,
...
...
ruoyi-admin/src/main/resources/templates/system/user/user.html
View file @
ec8c7f1d
...
...
@@ -73,6 +73,9 @@
<a
class=
"btn btn-danger btn-del disabled"
onclick=
"$.operate.removeAll()"
shiro:hasPermission=
"system:user:remove"
>
<i
class=
"fa fa-remove"
></i>
删除
</a>
<a
class=
"btn btn-info"
onclick=
"$.table.importExcel()"
shiro:hasPermission=
"system:user:import"
>
<i
class=
"fa fa-download"
></i>
导入
</a>
<a
class=
"btn btn-warning"
onclick=
"$.table.exportExcel()"
shiro:hasPermission=
"system:user:export"
>
<i
class=
"fa fa-download"
></i>
导出
</a>
...
...
@@ -83,6 +86,7 @@
</div>
</div>
</div>
<div
th:include=
"include :: footer"
></div>
<script
th:src=
"@{/ajax/libs/jquery-layout/jquery.layout-latest.js}"
></script>
<script
th:src=
"@{/ajax/libs/jquery-ztree/3.5/js/jquery.ztree.all-3.5.js}"
></script>
...
...
@@ -106,6 +110,8 @@
updateUrl
:
prefix
+
"/edit/{id}"
,
removeUrl
:
prefix
+
"/remove"
,
exportUrl
:
prefix
+
"/export"
,
importUrl
:
prefix
+
"/importData"
,
importTemplateUrl
:
prefix
+
"/importTemplate"
,
sortName
:
"createTime"
,
sortOrder
:
"desc"
,
modalName
:
"用户"
,
...
...
@@ -214,4 +220,16 @@
}
</script>
</body>
<form
id=
"importForm"
enctype=
"multipart/form-data"
class=
"mt20 mb10"
style=
"display: none;"
>
<div
class=
"col-xs-offset-1"
>
<input
type=
"file"
id=
"file"
name=
"file"
/>
<div
class=
"mt10 pt5"
>
<input
type=
"checkbox"
id=
"updateSupport"
name=
"updateSupport"
title=
"如果登录账户已经存在,更新这条数据。"
>
是否更新已经存在的用户数据
<a
onclick=
"$.table.importTemplate()"
class=
"btn btn-default btn-xs"
><i
class=
"fa fa-file-excel-o"
></i>
下载模板
</a>
</div>
<font
color=
"red"
class=
"pull-left mt10"
>
提示:仅允许导入“xls”或“xlsx”格式文件!
</font>
</div>
</form>
</html>
\ No newline at end of file
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java
View file @
ec8c7f1d
...
...
@@ -37,7 +37,7 @@ public @interface Excel
/**
* 导出时在excel中每个列的宽 单位为字符
*/
public
double
width
()
default
20
;
public
double
width
()
default
16
;
/**
* 文字后缀,如% 90 变成90%
...
...
@@ -68,4 +68,25 @@ public @interface Excel
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public
String
targetAttr
()
default
""
;
/**
* 字段类型( 1:仅导出;2:仅导入)
*/
Type
type
()
default
Type
.
EXPORT
;
public
enum
Type
{
EXPORT
(
1
),
IMPORT
(
2
);
private
final
int
value
;
Type
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
return
this
.
value
;
}
}
}
\ No newline at end of file
ruoyi-common/src/main/java/com/ruoyi/common/reflect/ReflectUtils.java
0 → 100644
View file @
ec8c7f1d
package
com
.
ruoyi
.
common
.
reflect
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.util.Date
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.Validate
;
import
org.apache.poi.ss.usermodel.DateUtil
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.ruoyi.common.support.Convert
;
import
com.ruoyi.common.utils.DateUtils
;
/**
* 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*
* @author ruoyi
*/
@SuppressWarnings
(
"rawtypes"
)
public
class
ReflectUtils
{
private
static
final
String
SETTER_PREFIX
=
"set"
;
private
static
final
String
GETTER_PREFIX
=
"get"
;
private
static
final
String
CGLIB_CLASS_SEPARATOR
=
"$$"
;
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ReflectUtils
.
class
);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeGetter
(
Object
obj
,
String
propertyName
)
{
Object
object
=
obj
;
for
(
String
name
:
StringUtils
.
split
(
propertyName
,
"."
))
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
name
);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
return
(
E
)
object
;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public
static
<
E
>
void
invokeSetter
(
Object
obj
,
String
propertyName
,
E
value
)
{
Object
object
=
obj
;
String
[]
names
=
StringUtils
.
split
(
propertyName
,
"."
);
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
if
(
i
<
names
.
length
-
1
)
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
else
{
String
setterMethodName
=
SETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
invokeMethodByName
(
object
,
setterMethodName
,
new
Object
[]
{
value
});
}
}
}
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
getFieldValue
(
final
Object
obj
,
final
String
fieldName
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
null
;
}
E
result
=
null
;
try
{
result
=
(
E
)
field
.
get
(
obj
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常{}"
,
e
.
getMessage
());
}
return
result
;
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public
static
<
E
>
void
setFieldValue
(
final
Object
obj
,
final
String
fieldName
,
final
E
value
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
;
}
try
{
field
.
set
(
obj
,
value
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常: {}"
,
e
.
getMessage
());
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>[]
parameterTypes
,
final
Object
[]
args
)
{
if
(
obj
==
null
||
methodName
==
null
)
{
return
null
;
}
Method
method
=
getAccessibleMethod
(
obj
,
methodName
,
parameterTypes
);
if
(
method
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethodByName
(
final
Object
obj
,
final
String
methodName
,
final
Object
[]
args
)
{
Method
method
=
getAccessibleMethodByName
(
obj
,
methodName
,
args
.
length
);
if
(
method
==
null
)
{
// 如果为空不报错,直接返回空。
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
// 类型转换(将参数数据类型转换为目标方法参数类型)
Class
<?>[]
cs
=
method
.
getParameterTypes
();
for
(
int
i
=
0
;
i
<
cs
.
length
;
i
++)
{
if
(
args
[
i
]
!=
null
&&
!
args
[
i
].
getClass
().
equals
(
cs
[
i
]))
{
if
(
cs
[
i
]
==
String
.
class
)
{
args
[
i
]
=
Convert
.
toStr
(
args
[
i
]);
if
(
StringUtils
.
endsWith
((
String
)
args
[
i
],
".0"
))
{
args
[
i
]
=
StringUtils
.
substringBefore
((
String
)
args
[
i
],
".0"
);
}
}
else
if
(
cs
[
i
]
==
Integer
.
class
)
{
args
[
i
]
=
Convert
.
toInt
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Long
.
class
)
{
args
[
i
]
=
Convert
.
toLong
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Double
.
class
)
{
args
[
i
]
=
Convert
.
toDouble
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Float
.
class
)
{
args
[
i
]
=
Convert
.
toFloat
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Date
.
class
)
{
if
(
args
[
i
]
instanceof
String
)
{
args
[
i
]
=
DateUtils
.
parseDate
(
args
[
i
]);
}
else
{
args
[
i
]
=
DateUtil
.
getJavaDate
((
Double
)
args
[
i
]);
}
}
}
}
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
*/
public
static
Field
getAccessibleField
(
final
Object
obj
,
final
String
fieldName
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
fieldName
,
"fieldName can't be blank"
);
for
(
Class
<?>
superClass
=
obj
.
getClass
();
superClass
!=
Object
.
class
;
superClass
=
superClass
.
getSuperclass
())
{
try
{
Field
field
=
superClass
.
getDeclaredField
(
fieldName
);
makeAccessible
(
field
);
return
field
;
}
catch
(
NoSuchFieldException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 匹配函数名+参数类型。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>...
parameterTypes
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
())
{
try
{
Method
method
=
searchType
.
getDeclaredMethod
(
methodName
,
parameterTypes
);
makeAccessible
(
method
);
return
method
;
}
catch
(
NoSuchMethodException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 只匹配函数名。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethodByName
(
final
Object
obj
,
final
String
methodName
,
int
argsNum
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
())
{
Method
[]
methods
=
searchType
.
getDeclaredMethods
();
for
(
Method
method
:
methods
)
{
if
(
method
.
getName
().
equals
(
methodName
)
&&
method
.
getParameterTypes
().
length
==
argsNum
)
{
makeAccessible
(
method
);
return
method
;
}
}
}
return
null
;
}
/**
* 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Method
method
)
{
if
((!
Modifier
.
isPublic
(
method
.
getModifiers
())
||
!
Modifier
.
isPublic
(
method
.
getDeclaringClass
().
getModifiers
()))
&&
!
method
.
isAccessible
())
{
method
.
setAccessible
(
true
);
}
}
/**
* 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Field
field
)
{
if
((!
Modifier
.
isPublic
(
field
.
getModifiers
())
||
!
Modifier
.
isPublic
(
field
.
getDeclaringClass
().
getModifiers
())
||
Modifier
.
isFinal
(
field
.
getModifiers
()))
&&
!
field
.
isAccessible
())
{
field
.
setAccessible
(
true
);
}
}
/**
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
Class
<
T
>
getClassGenricType
(
final
Class
clazz
)
{
return
getClassGenricType
(
clazz
,
0
);
}
/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*/
public
static
Class
getClassGenricType
(
final
Class
clazz
,
final
int
index
)
{
Type
genType
=
clazz
.
getGenericSuperclass
();
if
(!(
genType
instanceof
ParameterizedType
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
"'s superclass not ParameterizedType"
);
return
Object
.
class
;
}
Type
[]
params
=
((
ParameterizedType
)
genType
).
getActualTypeArguments
();
if
(
index
>=
params
.
length
||
index
<
0
)
{
logger
.
debug
(
"Index: "
+
index
+
", Size of "
+
clazz
.
getSimpleName
()
+
"'s Parameterized Type: "
+
params
.
length
);
return
Object
.
class
;
}
if
(!(
params
[
index
]
instanceof
Class
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
" not set the actual class on superclass generic parameter"
);
return
Object
.
class
;
}
return
(
Class
)
params
[
index
];
}
public
static
Class
<?>
getUserClass
(
Object
instance
)
{
if
(
instance
==
null
)
{
throw
new
RuntimeException
(
"Instance must not be null"
);
}
Class
clazz
=
instance
.
getClass
();
if
(
clazz
!=
null
&&
clazz
.
getName
().
contains
(
CGLIB_CLASS_SEPARATOR
))
{
Class
<?>
superClass
=
clazz
.
getSuperclass
();
if
(
superClass
!=
null
&&
!
Object
.
class
.
equals
(
superClass
))
{
return
superClass
;
}
}
return
clazz
;
}
/**
* 将反射时的checked exception转换为unchecked exception.
*/
public
static
RuntimeException
convertReflectionExceptionToUnchecked
(
String
msg
,
Exception
e
)
{
if
(
e
instanceof
IllegalAccessException
||
e
instanceof
IllegalArgumentException
||
e
instanceof
NoSuchMethodException
)
{
return
new
IllegalArgumentException
(
msg
,
e
);
}
else
if
(
e
instanceof
InvocationTargetException
)
{
return
new
RuntimeException
(
msg
,
((
InvocationTargetException
)
e
).
getTargetException
());
}
return
new
RuntimeException
(
msg
,
e
);
}
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelUtil.java
View file @
ec8c7f1d
...
...
@@ -7,7 +7,7 @@ import java.io.InputStream;
import
java.io.OutputStream
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.text.
SimpleDate
Format
;
import
java.text.
Decimal
Format
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.HashMap
;
...
...
@@ -15,30 +15,32 @@ import java.util.List;
import
java.util.Map
;
import
java.util.UUID
;
import
org.apache.poi.hssf.usermodel.DVConstraint
;
import
org.apache.poi.hssf.usermodel.HSSFCell
;
import
org.apache.poi.hssf.usermodel.HSSFCellStyle
;
import
org.apache.poi.hssf.usermodel.HSSFDataValidation
;
import
org.apache.poi.hssf.usermodel.HSSFDateUtil
;
import
org.apache.poi.hssf.usermodel.HSSFFont
;
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.HSSFColor.HSSFColorPredefined
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.CellStyle
;
import
org.apache.poi.ss.usermodel.CellType
;
import
org.apache.poi.ss.usermodel.DateUtil
;
import
org.apache.poi.ss.usermodel.FillPatternType
;
import
org.apache.poi.ss.usermodel.Font
;
import
org.apache.poi.ss.usermodel.HorizontalAlignment
;
import
org.apache.poi.ss.usermodel.Row
;
import
org.apache.poi.ss.usermodel.Sheet
;
import
org.apache.poi.ss.usermodel.VerticalAlignment
;
import
org.apache.poi.ss.usermodel.Workbook
;
import
org.apache.poi.ss.usermodel.WorkbookFactory
;
import
org.apache.poi.ss.util.CellRangeAddressList
;
import
org.apache.poi.xssf.streaming.SXSSFWorkbook
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.ruoyi.common.annotation.Excel
;
import
com.ruoyi.common.annotation.Excel.Type
;
import
com.ruoyi.common.base.AjaxResult
;
import
com.ruoyi.common.config.Global
;
import
com.ruoyi.common.exception.BusinessException
;
import
com.ruoyi.common.reflect.ReflectUtils
;
/**
* Excel相关处理
...
...
@@ -49,6 +51,44 @@ public class ExcelUtil<T>
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
ExcelUtil
.
class
);
/**
* Excel sheet最大行数,默认65536
*/
public
static
final
int
sheetSize
=
65536
;
/**
* 工作表名称
*/
private
String
sheetName
;
/**
* 导出类型(EXPORT:导出数据;IMPORT:导入模板)
*/
private
Type
type
;
/**
* 工作薄对象
*/
private
Workbook
wb
;
/**
* 工作表对象
*/
private
Sheet
sheet
;
/**
* 导入导出数据列表
*/
private
List
<
T
>
list
;
/**
* 注解列表
*/
private
List
<
Field
>
fields
;
/**
* 实体对象
*/
public
Class
<
T
>
clazz
;
public
ExcelUtil
(
Class
<
T
>
clazz
)
...
...
@@ -56,15 +96,28 @@ public class ExcelUtil<T>
this
.
clazz
=
clazz
;
}
public
void
init
(
List
<
T
>
list
,
String
sheetName
,
Type
type
)
{
if
(
list
==
null
)
{
list
=
new
ArrayList
<
T
>();
}
this
.
list
=
list
;
this
.
sheetName
=
sheetName
;
this
.
type
=
type
;
createExcelField
();
createWorkbook
();
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param input 输入流
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
InputStream
i
nput
)
throws
Exception
public
List
<
T
>
importExcel
(
InputStream
i
s
)
throws
Exception
{
return
importExcel
(
StringUtils
.
EMPTY
,
i
nput
);
return
importExcel
(
StringUtils
.
EMPTY
,
i
s
);
}
/**
...
...
@@ -74,21 +127,20 @@ public class ExcelUtil<T>
* @param input 输入流
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
String
sheetName
,
InputStream
i
nput
)
throws
Exception
public
List
<
T
>
importExcel
(
String
sheetName
,
InputStream
i
s
)
throws
Exception
{
this
.
wb
=
new
XSSFWorkbook
(
is
);
List
<
T
>
list
=
new
ArrayList
<
T
>();
Workbook
workbook
=
WorkbookFactory
.
create
(
input
);
Sheet
sheet
=
null
;
if
(
StringUtils
.
isNotEmpty
(
sheetName
))
{
// 如果指定sheet名,则取指定sheet中的内容.
sheet
=
w
orkbook
.
getSheet
(
sheetName
);
sheet
=
w
b
.
getSheet
(
sheetName
);
}
else
{
// 如果传入的sheet名不存在则默认指向第1个sheet.
sheet
=
w
orkbook
.
getSheetAt
(
0
);
sheet
=
w
b
.
getSheetAt
(
0
);
}
if
(
sheet
==
null
)
...
...
@@ -123,88 +175,77 @@ public class ExcelUtil<T>
Row
row
=
sheet
.
getRow
(
i
);
int
cellNum
=
serialNum
;
T
entity
=
null
;
for
(
int
j
=
0
;
j
<
cellNum
;
j
++)
for
(
int
column
=
0
;
column
<
cellNum
;
column
++)
{
Cell
cell
=
row
.
getCell
(
j
);
if
(
cell
==
null
)
{
continue
;
}
else
{
// 先设置Cell的类型,然后就可以把纯数字作为String类型读进来了
row
.
getCell
(
j
).
setCellType
(
CellType
.
STRING
);
cell
=
row
.
getCell
(
j
);
}
String
c
=
cell
.
getStringCellValue
();
if
(
StringUtils
.
isEmpty
(
c
))
{
continue
;
}
Object
val
=
this
.
getCellValue
(
row
,
column
);
// 如果不存在实例则新建.
entity
=
(
entity
==
null
?
clazz
.
newInstance
()
:
entity
);
// 从map中得到对应列的field.
Field
field
=
fieldsMap
.
get
(
j
+
1
);
Field
field
=
fieldsMap
.
get
(
column
+
1
);
// 取得类型,并根据对象类型设置值.
Class
<?>
fieldType
=
field
.
getType
();
if
(
String
.
class
==
fieldType
)
{
field
.
set
(
entity
,
String
.
valueOf
(
c
));
String
s
=
String
.
valueOf
(
val
.
toString
());
if
(
StringUtils
.
endsWith
(
s
,
".0"
))
{
val
=
StringUtils
.
substringBefore
(
s
,
".0"
);
}
else
{
val
=
String
.
valueOf
(
val
.
toString
());
}
}
else
if
((
Integer
.
TYPE
==
fieldType
)
||
(
Integer
.
class
==
fieldType
))
{
field
.
set
(
entity
,
Integer
.
parseInt
(
c
)
);
val
=
Double
.
valueOf
(
val
.
toString
()).
intValue
(
);
}
else
if
((
Long
.
TYPE
==
fieldType
)
||
(
Long
.
class
==
fieldType
))
{
field
.
set
(
entity
,
Long
.
valueOf
(
c
)
);
val
=
Double
.
valueOf
(
val
.
toString
()).
longValue
(
);
}
else
if
((
Float
.
TYPE
==
fieldType
)
||
(
Float
.
class
==
fieldType
))
{
field
.
set
(
entity
,
Float
.
valueOf
(
c
));
}
else
if
((
Short
.
TYPE
==
fieldType
)
||
(
Short
.
class
==
fieldType
))
else
if
((
Double
.
TYPE
==
fieldType
)
||
(
Double
.
class
==
fieldType
))
{
field
.
set
(
entity
,
Short
.
valueOf
(
c
));
val
=
Double
.
valueOf
(
val
.
toString
(
));
}
else
if
((
Double
.
TYPE
==
fieldType
)
||
(
Double
.
class
==
fieldType
))
else
if
((
Float
.
TYPE
==
fieldType
)
||
(
Float
.
class
==
fieldType
))
{
field
.
set
(
entity
,
Double
.
valueOf
(
c
));
val
=
Float
.
valueOf
(
val
.
toString
(
));
}
else
if
(
Character
.
TYPE
==
fieldType
)
else
if
(
Date
.
class
==
fieldType
)
{
if
((
c
!=
null
)
&&
(
c
.
length
()
>
0
))
if
(
val
instanceof
String
)
{
val
=
DateUtils
.
parseDate
(
val
);
}
else
if
(
val
instanceof
Double
)
{
field
.
set
(
entity
,
Character
.
valueOf
(
c
.
charAt
(
0
))
);
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
}
}
else
if
(
java
.
util
.
Date
.
class
==
fieldType
)
if
(
StringUtils
.
isNotNull
(
fieldType
)
)
{
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
NUMERIC
)
Excel
attr
=
field
.
getAnnotation
(
Excel
.
class
);
if
(
StringUtils
.
isNotEmpty
(
attr
.
targetAttr
()))
{
SimpleDateFormat
sdf
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
cell
.
setCellValue
(
sdf
.
format
(
cell
.
getNumericCellValue
()));
c
=
sdf
.
format
(
cell
.
getNumericCellValue
());
ReflectUtils
.
invokeSetter
(
entity
,
field
.
getName
()
+
"."
+
attr
.
targetAttr
(),
val
);
}
else
if
(
StringUtils
.
isNotEmpty
(
attr
.
readConverterExp
()))
{
String
value
=
reverseByExp
(
String
.
valueOf
(
val
),
attr
.
readConverterExp
());
ReflectUtils
.
invokeSetter
(
entity
,
field
.
getName
()
+
"."
+
attr
.
targetAttr
(),
value
);
}
else
{
c
=
cell
.
getStringCellValue
(
);
ReflectUtils
.
invokeSetter
(
entity
,
field
.
getName
(),
val
);
}
}
else
if
(
java
.
math
.
BigDecimal
.
class
==
fieldType
)
{
c
=
cell
.
getStringCellValue
();
}
}
if
(
entity
!=
null
)
{
list
.
add
(
entity
);
}
list
.
add
(
entity
);
}
}
return
list
;
}
...
...
@@ -217,46 +258,41 @@ public class ExcelUtil<T>
*/
public
AjaxResult
exportExcel
(
List
<
T
>
list
,
String
sheetName
)
{
this
.
init
(
list
,
sheetName
,
Type
.
EXPORT
);
return
exportExcel
();
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @return 结果
*/
public
AjaxResult
importTemplateExcel
(
String
sheetName
)
{
this
.
init
(
null
,
sheetName
,
Type
.
IMPORT
);
return
exportExcel
();
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @return 结果
*/
public
AjaxResult
exportExcel
()
{
OutputStream
out
=
null
;
HSSFWorkbook
workbook
=
null
;
try
{
// 得到所有定义字段
Field
[]
allFields
=
clazz
.
getDeclaredFields
();
List
<
Field
>
fields
=
new
ArrayList
<
Field
>();
// 得到所有field并存放到一个list中.
for
(
Field
field
:
allFields
)
{
if
(
field
.
isAnnotationPresent
(
Excel
.
class
))
{
fields
.
add
(
field
);
}
}
// 产生工作薄对象
workbook
=
new
HSSFWorkbook
();
// excel2003中每个sheet中最多有65536行
int
sheetSize
=
65536
;
// 取出一共有多少个sheet.
double
sheetNo
=
Math
.
ceil
(
list
.
size
()
/
sheetSize
);
for
(
int
index
=
0
;
index
<=
sheetNo
;
index
++)
{
// 产生工作表对象
HSSFSheet
sheet
=
workbook
.
createSheet
();
if
(
sheetNo
==
0
)
{
workbook
.
setSheetName
(
index
,
sheetName
);
}
else
{
// 设置工作表的名称.
workbook
.
setSheetName
(
index
,
sheetName
+
index
);
}
HSSFRow
row
;
HSSFCell
cell
;
// 产生单元格
createSheet
(
sheetNo
,
index
);
Cell
cell
=
null
;
// 产生单元格
// 产生一行
row
=
sheet
.
createRow
(
0
);
Row
row
=
sheet
.
createRow
(
0
);
// 写入各个字段的列头名称
for
(
int
i
=
0
;
i
<
fields
.
size
();
i
++)
{
...
...
@@ -266,12 +302,12 @@ public class ExcelUtil<T>
cell
=
row
.
createCell
(
i
);
// 设置列中写入内容为String类型
cell
.
setCellType
(
CellType
.
STRING
);
HSSFCellStyle
cellStyle
=
workbook
.
createCellStyle
();
CellStyle
cellStyle
=
wb
.
createCellStyle
();
cellStyle
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
cellStyle
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
if
(
attr
.
name
().
indexOf
(
"注:"
)
>=
0
)
{
HSSFFont
font
=
workbook
.
createFont
();
Font
font
=
wb
.
createFont
();
font
.
setColor
(
HSSFFont
.
COLOR_RED
);
cellStyle
.
setFont
(
font
);
cellStyle
.
setFillForegroundColor
(
HSSFColorPredefined
.
YELLOW
.
getIndex
());
...
...
@@ -279,7 +315,7 @@ public class ExcelUtil<T>
}
else
{
HSSFFont
font
=
workbook
.
createFont
();
Font
font
=
wb
.
createFont
();
// 粗体显示
font
.
setBold
(
true
);
// 选择需要用到的字体格式
...
...
@@ -309,72 +345,14 @@ public class ExcelUtil<T>
setHSSFValidation
(
sheet
,
attr
.
combo
(),
1
,
100
,
i
,
i
);
}
}
int
startNo
=
index
*
sheetSize
;
int
endNo
=
Math
.
min
(
startNo
+
sheetSize
,
list
.
size
());
// 写入各条记录,每条记录对应excel表中的一行
HSSFCellStyle
cs
=
workbook
.
createCellStyle
();
cs
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
cs
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
for
(
int
i
=
startNo
;
i
<
endNo
;
i
++)
if
(
Type
.
EXPORT
.
equals
(
type
))
{
row
=
sheet
.
createRow
(
i
+
1
-
startNo
);
// 得到导出对象.
T
vo
=
(
T
)
list
.
get
(
i
);
for
(
int
j
=
0
;
j
<
fields
.
size
();
j
++)
{
// 获得field.
Field
field
=
fields
.
get
(
j
);
// 设置实体类私有属性可访问
field
.
setAccessible
(
true
);
Excel
attr
=
field
.
getAnnotation
(
Excel
.
class
);
try
{
// 设置行高
row
.
setHeight
((
short
)
(
attr
.
height
()
*
20
));
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
if
(
attr
.
isExport
())
{
// 创建cell
cell
=
row
.
createCell
(
j
);
cell
.
setCellStyle
(
cs
);
if
(
vo
==
null
)
{
// 如果数据存在就填入,不存在填入空格.
cell
.
setCellValue
(
""
);
continue
;
}
// 用于读取对象中的属性
Object
value
=
getTargetValue
(
vo
,
field
,
attr
);
String
dateFormat
=
attr
.
dateFormat
();
String
readConverterExp
=
attr
.
readConverterExp
();
if
(
StringUtils
.
isNotEmpty
(
dateFormat
))
{
cell
.
setCellValue
(
DateUtils
.
parseDateToStr
(
dateFormat
,
(
Date
)
value
));
}
else
if
(
StringUtils
.
isNotEmpty
(
readConverterExp
))
{
cell
.
setCellValue
(
convertByExp
(
String
.
valueOf
(
value
),
readConverterExp
));
}
else
{
cell
.
setCellType
(
CellType
.
STRING
);
// 如果数据存在就填入,不存在填入空格.
cell
.
setCellValue
(
StringUtils
.
isNull
(
value
)
?
attr
.
defaultValue
()
:
value
+
attr
.
suffix
());
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel失败{}"
,
e
.
getMessage
());
}
}
fillExcelData
(
index
,
row
,
cell
);
}
}
String
filename
=
encodingFilename
(
sheetName
);
out
=
new
FileOutputStream
(
getAbsoluteFile
(
filename
));
w
orkbook
.
write
(
out
);
w
b
.
write
(
out
);
return
AjaxResult
.
success
(
filename
);
}
catch
(
Exception
e
)
...
...
@@ -384,11 +362,11 @@ public class ExcelUtil<T>
}
finally
{
if
(
w
orkbook
!=
null
)
if
(
w
b
!=
null
)
{
try
{
w
orkbook
.
close
();
w
b
.
close
();
}
catch
(
IOException
e1
)
{
...
...
@@ -410,6 +388,78 @@ public class ExcelUtil<T>
}
/**
* 填充excel数据
*
* @param index 序号
* @param row 单元格行
* @param cell 类型单元格
*/
public
void
fillExcelData
(
int
index
,
Row
row
,
Cell
cell
)
{
int
startNo
=
index
*
sheetSize
;
int
endNo
=
Math
.
min
(
startNo
+
sheetSize
,
list
.
size
());
// 写入各条记录,每条记录对应excel表中的一行
CellStyle
cs
=
wb
.
createCellStyle
();
cs
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
cs
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
for
(
int
i
=
startNo
;
i
<
endNo
;
i
++)
{
row
=
sheet
.
createRow
(
i
+
1
-
startNo
);
// 得到导出对象.
T
vo
=
(
T
)
list
.
get
(
i
);
for
(
int
j
=
0
;
j
<
fields
.
size
();
j
++)
{
// 获得field.
Field
field
=
fields
.
get
(
j
);
// 设置实体类私有属性可访问
field
.
setAccessible
(
true
);
Excel
attr
=
field
.
getAnnotation
(
Excel
.
class
);
try
{
// 设置行高
row
.
setHeight
((
short
)
(
attr
.
height
()
*
20
));
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
if
(
attr
.
isExport
())
{
// 创建cell
cell
=
row
.
createCell
(
j
);
cell
.
setCellStyle
(
cs
);
if
(
vo
==
null
)
{
// 如果数据存在就填入,不存在填入空格.
cell
.
setCellValue
(
""
);
continue
;
}
// 用于读取对象中的属性
Object
value
=
getTargetValue
(
vo
,
field
,
attr
);
String
dateFormat
=
attr
.
dateFormat
();
String
readConverterExp
=
attr
.
readConverterExp
();
if
(
StringUtils
.
isNotEmpty
(
dateFormat
))
{
cell
.
setCellValue
(
DateUtils
.
parseDateToStr
(
dateFormat
,
(
Date
)
value
));
}
else
if
(
StringUtils
.
isNotEmpty
(
readConverterExp
))
{
cell
.
setCellValue
(
convertByExp
(
String
.
valueOf
(
value
),
readConverterExp
));
}
else
{
cell
.
setCellType
(
CellType
.
STRING
);
// 如果数据存在就填入,不存在填入空格.
cell
.
setCellValue
(
StringUtils
.
isNull
(
value
)
?
attr
.
defaultValue
()
:
value
+
attr
.
suffix
());
}
}
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel失败{}"
,
e
.
getMessage
());
}
}
}
}
/**
* 设置单元格上提示
*
* @param sheet 要设置的sheet.
...
...
@@ -421,8 +471,8 @@ public class ExcelUtil<T>
* @param endCol 结束列
* @return 设置好的sheet.
*/
public
static
HSSFSheet
setHSSFPrompt
(
HSSFSheet
sheet
,
String
promptTitle
,
String
promptContent
,
int
first
Row
,
int
endRow
,
int
firstCol
,
int
endCol
)
public
static
Sheet
setHSSFPrompt
(
Sheet
sheet
,
String
promptTitle
,
String
promptContent
,
int
firstRow
,
int
end
Row
,
int
firstCol
,
int
endCol
)
{
// 构造constraint对象
DVConstraint
constraint
=
DVConstraint
.
createCustomFormulaConstraint
(
"DD1"
);
...
...
@@ -446,8 +496,8 @@ public class ExcelUtil<T>
* @param endCol 结束列
* @return 设置好的sheet.
*/
public
static
HSSFSheet
setHSSFValidation
(
HSSFSheet
sheet
,
String
[]
textlist
,
int
firstRow
,
int
endRow
,
int
firstCol
,
int
endCol
)
public
static
Sheet
setHSSFValidation
(
Sheet
sheet
,
String
[]
textlist
,
int
firstRow
,
int
endRow
,
int
firstCol
,
int
endCol
)
{
// 加载下拉列表内容
DVConstraint
constraint
=
DVConstraint
.
createExplicitListConstraint
(
textlist
);
...
...
@@ -489,11 +539,40 @@ public class ExcelUtil<T>
}
/**
* 反向解析值 男=0,女=1,未知=2
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @return 解析后值
* @throws Exception
*/
public
static
String
reverseByExp
(
String
propertyValue
,
String
converterExp
)
throws
Exception
{
try
{
String
[]
convertSource
=
converterExp
.
split
(
","
);
for
(
String
item
:
convertSource
)
{
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
itemArray
[
1
].
equals
(
propertyValue
))
{
return
itemArray
[
0
];
}
}
}
catch
(
Exception
e
)
{
throw
e
;
}
return
propertyValue
;
}
/**
* 编码文件名
*/
public
String
encodingFilename
(
String
filename
)
{
filename
=
UUID
.
randomUUID
().
toString
()
+
"_"
+
filename
+
".xls"
;
filename
=
UUID
.
randomUUID
().
toString
()
+
"_"
+
filename
+
".xls
x
"
;
return
filename
;
}
...
...
@@ -563,4 +642,110 @@ public class ExcelUtil<T>
}
return
o
;
}
/**
* 得到所有定义字段
*/
private
void
createExcelField
()
{
this
.
fields
=
new
ArrayList
<
Field
>();
Field
[]
allFields
=
clazz
.
getDeclaredFields
();
// 得到所有field并存放到一个list中.
for
(
Field
field
:
allFields
)
{
if
(
field
.
isAnnotationPresent
(
Excel
.
class
))
{
fields
.
add
(
field
);
}
}
}
/**
* 创建一个工作簿
*/
public
void
createWorkbook
()
{
this
.
wb
=
new
SXSSFWorkbook
(
500
);
}
/**
* 创建工作表
*
* @param sheetName,指定Sheet名称
* @param sheetNo sheet数量
* @param index 序号
*/
public
void
createSheet
(
double
sheetNo
,
int
index
)
{
this
.
sheet
=
wb
.
createSheet
();
// 设置工作表的名称.
if
(
sheetNo
==
0
)
{
wb
.
setSheetName
(
index
,
sheetName
);
}
else
{
wb
.
setSheetName
(
index
,
sheetName
+
index
);
}
}
/**
* 获取单元格值
*
* @param row 获取的行
* @param column 获取单元格列号
* @return 单元格值
*/
public
Object
getCellValue
(
Row
row
,
int
column
)
{
if
(
row
==
null
)
{
return
row
;
}
Object
val
=
""
;
try
{
Cell
cell
=
row
.
getCell
(
column
);
if
(
cell
!=
null
)
{
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
NUMERIC
)
{
val
=
cell
.
getNumericCellValue
();
if
(
HSSFDateUtil
.
isCellDateFormatted
(
cell
))
{
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
// POI Excel 日期格式转换
}
else
{
if
((
Double
)
val
%
1
>
0
)
{
val
=
new
DecimalFormat
(
"0.00"
).
format
(
val
);
}
else
{
val
=
new
DecimalFormat
(
"0"
).
format
(
val
);
}
}
}
else
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
STRING
)
{
val
=
cell
.
getStringCellValue
();
}
else
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
BOOLEAN
)
{
val
=
cell
.
getBooleanCellValue
();
}
else
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
ERROR
)
{
val
=
cell
.
getErrorCellValue
();
}
}
}
catch
(
Exception
e
)
{
return
val
;
}
return
val
;
}
}
\ No newline at end of file
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUser.java
View file @
ec8c7f1d
...
...
@@ -244,6 +244,10 @@ public class SysUser extends BaseEntity
public
SysDept
getDept
()
{
if
(
dept
==
null
)
{
dept
=
new
SysDept
();
}
return
dept
;
}
...
...
@@ -304,6 +308,7 @@ public class SysUser extends BaseEntity
.
append
(
"updateBy"
,
getUpdateBy
())
.
append
(
"updateTime"
,
getUpdateTime
())
.
append
(
"remark"
,
getRemark
())
.
append
(
"dept"
,
getDept
())
.
toString
();
}
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
View file @
ec8c7f1d
...
...
@@ -138,4 +138,12 @@ public interface ISysUserService
* @return 结果
*/
public
String
selectUserPostGroup
(
Long
userId
);
/**
* 导入用户数据
*
* @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
* @return 结果
*/
public
String
importUser
(
List
<
SysUser
>
userList
,
Boolean
isUpdateSupport
);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
View file @
ec8c7f1d
...
...
@@ -2,6 +2,8 @@ package com.ruoyi.system.service.impl;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
com.ruoyi.common.annotation.DataScope
;
...
...
@@ -29,6 +31,8 @@ import com.ruoyi.system.service.ISysUserService;
@Service
public
class
SysUserServiceImpl
implements
ISysUserService
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
SysUserServiceImpl
.
class
);
@Autowired
private
SysUserMapper
userMapper
;
...
...
@@ -212,18 +216,22 @@ public class SysUserServiceImpl implements ISysUserService
*/
public
void
insertUserRole
(
SysUser
user
)
{
// 新增用户与角色管理
List
<
SysUserRole
>
list
=
new
ArrayList
<
SysUserRole
>();
for
(
Long
roleId
:
user
.
getRoleIds
())
Long
[]
roles
=
user
.
getRoleIds
();
if
(
StringUtils
.
isNotNull
(
roles
))
{
SysUserRole
ur
=
new
SysUserRole
();
ur
.
setUserId
(
user
.
getUserId
());
ur
.
setRoleId
(
roleId
);
list
.
add
(
ur
);
}
if
(
list
.
size
()
>
0
)
{
userRoleMapper
.
batchUserRole
(
list
);
// 新增用户与角色管理
List
<
SysUserRole
>
list
=
new
ArrayList
<
SysUserRole
>();
for
(
Long
roleId
:
roles
)
{
SysUserRole
ur
=
new
SysUserRole
();
ur
.
setUserId
(
user
.
getUserId
());
ur
.
setRoleId
(
roleId
);
list
.
add
(
ur
);
}
if
(
list
.
size
()
>
0
)
{
userRoleMapper
.
batchUserRole
(
list
);
}
}
}
...
...
@@ -234,18 +242,22 @@ public class SysUserServiceImpl implements ISysUserService
*/
public
void
insertUserPost
(
SysUser
user
)
{
// 新增用户与岗位管理
List
<
SysUserPost
>
list
=
new
ArrayList
<
SysUserPost
>();
for
(
Long
postId
:
user
.
getPostIds
())
Long
[]
posts
=
user
.
getPostIds
();
if
(
StringUtils
.
isNotNull
(
posts
))
{
SysUserPost
up
=
new
SysUserPost
();
up
.
setUserId
(
user
.
getUserId
());
up
.
setPostId
(
postId
);
list
.
add
(
up
);
}
if
(
list
.
size
()
>
0
)
{
userPostMapper
.
batchUserPost
(
list
);
// 新增用户与岗位管理
List
<
SysUserPost
>
list
=
new
ArrayList
<
SysUserPost
>();
for
(
Long
postId
:
posts
)
{
SysUserPost
up
=
new
SysUserPost
();
up
.
setUserId
(
user
.
getUserId
());
up
.
setPostId
(
postId
);
list
.
add
(
up
);
}
if
(
list
.
size
()
>
0
)
{
userPostMapper
.
batchUserPost
(
list
);
}
}
}
...
...
@@ -345,4 +357,64 @@ public class SysUserServiceImpl implements ISysUserService
}
return
idsStr
.
toString
();
}
/**
* 导入用户数据
*
* @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
* @return 结果
*/
public
String
importUser
(
List
<
SysUser
>
userList
,
Boolean
isUpdateSupport
)
{
if
(
StringUtils
.
isNull
(
userList
)
||
userList
.
size
()
==
0
)
{
throw
new
BusinessException
(
"导入用户数据不能为空!"
);
}
int
successNum
=
0
;
int
failureNum
=
0
;
StringBuilder
successMsg
=
new
StringBuilder
();
StringBuilder
failureMsg
=
new
StringBuilder
();
for
(
SysUser
user
:
userList
)
{
try
{
// 验证是否存在这个用户
SysUser
u
=
userMapper
.
selectUserByLoginName
(
user
.
getLoginName
());
if
(
StringUtils
.
isNull
(
u
))
{
this
.
insertUser
(
user
);
successNum
++;
successMsg
.
append
(
"<br/>"
+
successNum
+
"、账号 "
+
user
.
getLoginName
()
+
" 导入成功"
);
}
else
if
(
isUpdateSupport
)
{
this
.
updateUser
(
user
);
successNum
++;
successMsg
.
append
(
"<br/>"
+
successNum
+
"、账号 "
+
user
.
getLoginName
()
+
" 更新成功"
);
}
else
{
failureNum
++;
failureMsg
.
append
(
"<br/>"
+
failureNum
+
"、账号 "
+
user
.
getLoginName
()
+
" 已存在"
);
}
}
catch
(
Exception
e
)
{
failureNum
++;
String
msg
=
"<br/>"
+
failureNum
+
"、账号 "
+
user
.
getLoginName
()
+
" 导入失败:"
;
failureMsg
.
append
(
msg
+
e
.
getMessage
());
log
.
error
(
msg
,
e
);
}
}
if
(
failureNum
>
0
)
{
failureMsg
.
insert
(
0
,
"很抱歉,导入失败!共 "
+
failureNum
+
" 条数据格式不正确,错误如下:"
);
throw
new
BusinessException
(
failureMsg
.
toString
());
}
else
{
successMsg
.
insert
(
0
,
"恭喜您,数据已全部导入成功!共 "
+
successNum
+
" 条,数据如下:"
);
}
return
successMsg
.
toString
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment