Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
polysoft-nafmii
/
polysoft-parent
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 1170aa2f
authored
May 07, 2021
by
ypenglv
Browse Files
Options
Browse Files
Tag
Download
Plain Diff
Merge branch 'dev' of
http://gitlab.polyhome.net/polysoft-nafmii/polysoft-parent
into dev
2 parents
62a31463
7ff5739c
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
410 additions
and
753 deletions
nafmii-admin/src/main/java/org/nafmii/admin/user/controller/ImportExcelController.java
nafmii-admin/src/main/java/org/nafmii/admin/user/dao/ImportExcelMapper.java
nafmii-admin/src/main/java/org/nafmii/admin/user/dto/ImportExcelDto.java
nafmii-admin/src/main/java/org/nafmii/admin/user/entity/ImportExcelPO.java
nafmii-admin/src/main/java/org/nafmii/admin/user/service/IImportExcelService.java
nafmii-admin/src/main/java/org/nafmii/admin/user/service/impl/ImportExcelServiceImpl.java
nafmii-admin/src/main/resources/mapper/ImportExcelMapper.xml
nafmii-common/pom.xml
nafmii-common/src/main/java/org/nafmii/common/excle/Reflections.java
nafmii-common/src/main/java/org/nafmii/common/excle/annotation/ExcelField.java
nafmii-common/src/main/java/org/nafmii/common/excle/test.java
nafmii-common/src/main/java/org/nafmii/common/utils/ImportExcelUtils.java
nafmii-admin/src/main/java/org/nafmii/admin/user/controller/ImportExcelController.java
0 → 100644
View file @
1170aa2
package
org
.
nafmii
.
admin
.
user
.
controller
;
import
com.alibaba.excel.EasyExcel
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
org.nafmii.admin.user.dto.ImportExcelDto
;
import
org.nafmii.admin.user.service.IImportExcelService
;
import
org.nafmii.common.response.ApiResponse
;
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.bind.annotation.RestController
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.util.List
;
@RestController
@RequestMapping
(
"/nafmii/admin/import"
)
@Api
(
tags
=
"3.0.0"
,
description
=
"中心端批量导入Excel接口"
)
public
class
ImportExcelController
{
@Resource
private
IImportExcelService
iImportExcelService
;
@ApiOperation
(
value
=
"中心端批量导入Excel"
,
notes
=
"中心端批量导入Excel"
)
@PostMapping
(
"/batchImportExcel"
)
@ResponseBody
public
ApiResponse
batchImportExcel
(
MultipartFile
file
){
ApiResponse
result
=
iImportExcelService
.
batchImportExcel
(
file
);
return
result
;
}
}
nafmii-admin/src/main/java/org/nafmii/admin/user/dao/ImportExcelMapper.java
0 → 100644
View file @
1170aa2
package
org
.
nafmii
.
admin
.
user
.
dao
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.nafmii.admin.user.dto.ImportExcelDto
;
import
org.nafmii.admin.user.entity.CenterUserPO
;
import
java.util.List
;
/**
* <p>
* 中心端-用户表 Mapper 接口
* </p>
*
* @author suncq
* @since 2021-04-27
*/
@Mapper
public
interface
ImportExcelMapper
extends
BaseMapper
<
CenterUserPO
>
{
/**
* @author:suncq
* @Function:中心端用户登陆
* @date 2021/4/27
* @ClassName:
* @version:
* @remark:
*/
int
insertExcelData
(
ImportExcelDto
data
);
}
nafmii-admin/src/main/java/org/nafmii/admin/user/dto/ImportExcelDto.java
0 → 100644
View file @
1170aa2
package
org
.
nafmii
.
admin
.
user
.
dto
;
import
io.swagger.annotations.ApiModel
;
import
lombok.Data
;
@Data
@ApiModel
(
"导入Excel参数对象"
)
public
class
ImportExcelDto
{
private
String
column1
;
private
String
column2
;
private
String
column3
;
}
nafmii-admin/src/main/java/org/nafmii/admin/user/entity/ImportExcelPO.java
0 → 100644
View file @
1170aa2
package
org
.
nafmii
.
admin
.
user
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
com.baomidou.mybatisplus.extension.activerecord.Model
;
import
io.swagger.annotations.ApiModel
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
@Data
@EqualsAndHashCode
(
callSuper
=
true
)
@Accessors
(
chain
=
true
)
@TableName
(
"IMPORT_EXCEL_TEST"
)
@ApiModel
(
value
=
"导入ExcelPO对象"
,
description
=
"导入excel测试表"
)
public
class
ImportExcelPO
extends
Model
{
private
String
column1
;
private
String
column2
;
private
String
column3
;
}
nafmii-admin/src/main/java/org/nafmii/admin/user/service/IImportExcelService.java
0 → 100644
View file @
1170aa2
package
org
.
nafmii
.
admin
.
user
.
service
;
import
org.nafmii.admin.user.dto.ImportExcelDto
;
import
org.nafmii.common.response.ApiResponse
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.List
;
/**
* <p>
* 中心端-用户表 服务类
* </p>
*
* @author suncq
* @since 2021-04-27
*/
public
interface
IImportExcelService
{
/**
* @author:suncq
* @Function:中心端用户登陆
* @date 2021/4/27
* @ClassName:
* @version:
* @remark:
*/
ApiResponse
batchImportExcel
(
MultipartFile
file
);
}
nafmii-admin/src/main/java/org/nafmii/admin/user/service/impl/ImportExcelServiceImpl.java
0 → 100644
View file @
1170aa2
package
org
.
nafmii
.
admin
.
user
.
service
.
impl
;
import
com.alibaba.excel.EasyExcel
;
import
lombok.extern.slf4j.Slf4j
;
import
org.nafmii.admin.user.dao.ImportExcelMapper
;
import
org.nafmii.admin.user.dto.ImportExcelDto
;
import
org.nafmii.admin.user.service.IImportExcelService
;
import
org.nafmii.common.response.ApiResponse
;
import
org.springframework.stereotype.Service
;
import
org.apache.poi.hssf.usermodel.HSSFWorkbook
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.Row
;
import
org.apache.poi.ss.usermodel.Sheet
;
import
org.apache.poi.ss.usermodel.Workbook
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
org.nafmii.admin.user.service.IImportExcelService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* <p>
* 中心端-用户表 服务实现类
* </p>
*
* @author suncq
* @since 2021-04-27
*/
@Slf4j
@Service
public
class
ImportExcelServiceImpl
implements
IImportExcelService
{
@Resource
private
ImportExcelMapper
importExcelMapper
;
@Override
public
ApiResponse
batchImportExcel
(
MultipartFile
file
)
{
List
<
ImportExcelDto
>
list
=
null
;
try
{
list
=
EasyExcel
.
read
(
file
.
getInputStream
()).
sheet
(
0
).
head
(
ImportExcelDto
.
class
).
doReadSync
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
log
.
info
(
"导入后生成的数据源=============>"
+
list
);
if
(!
list
.
isEmpty
())
{
for
(
ImportExcelDto
data
:
list
)
{
int
i
=
importExcelMapper
.
insertExcelData
(
data
);
if
(
i
<
0
){
return
new
ApiResponse
(
ApiResponse
.
FAIL
,
ApiResponse
.
FAIL_TEXT
);
}
}
}
return
new
ApiResponse
(
ApiResponse
.
SUCCESS
,
ApiResponse
.
SUCCESS_TEXT
);
}
public
String
importExcel
(
InputStream
inputStream
,
String
fileName
)
throws
Exception
{
String
message
=
"Import success"
;
boolean
isE2007
=
false
;
//判断是否是excel2007格式
if
(
fileName
.
endsWith
(
"xlsx"
))
{
isE2007
=
true
;
}
int
rowIndex
=
0
;
try
{
InputStream
input
=
inputStream
;
//建立输入流
Workbook
wb
;
//根据文件格式(2003或者2007)来初始化
if
(
isE2007
)
{
wb
=
new
XSSFWorkbook
(
input
);
}
else
{
wb
=
new
HSSFWorkbook
(
input
);
}
Sheet
sheet
=
wb
.
getSheetAt
(
0
);
//获得第一个表单
int
rowCount
=
sheet
.
getLastRowNum
()
+
1
;
for
(
int
i
=
1
;
i
<
rowCount
;
i
++)
{
rowIndex
=
i
;
Row
row
;
for
(
int
j
=
0
;
j
<
26
;
j
++)
{
if
(
isMergedRegion
(
sheet
,
i
,
j
))
{
System
.
out
.
print
(
getMergedRegionValue
(
sheet
,
i
,
j
)
+
"\t"
);
}
else
{
row
=
sheet
.
getRow
(
i
);
System
.
out
.
print
(
row
.
getCell
(
j
)
+
"\t"
);
}
}
System
.
out
.
print
(
"\n"
);
}
}
catch
(
Exception
ex
)
{
message
=
"Import failed, please check the data in "
+
rowIndex
+
" rows "
;
}
return
message
;
}
/**
* 获取单元格的值
*
* @param cell
* @return
*/
public
String
getCellValue
(
Cell
cell
)
{
if
(
cell
==
null
)
return
""
;
return
cell
.
getStringCellValue
();
}
/**
* 合并单元格处理,获取合并行
*
* @param sheet
* @return List<CellRangeAddress>
*/
public
List
<
CellRangeAddress
>
getCombineCell
(
Sheet
sheet
)
{
List
<
CellRangeAddress
>
list
=
new
ArrayList
<>();
//获得一个 sheet 中合并单元格的数量
int
sheetmergerCount
=
sheet
.
getNumMergedRegions
();
//遍历所有的合并单元格
for
(
int
i
=
0
;
i
<
sheetmergerCount
;
i
++)
{
//获得合并单元格保存进list中
CellRangeAddress
ca
=
sheet
.
getMergedRegion
(
i
);
list
.
add
(
ca
);
}
return
list
;
}
private
int
getRowNum
(
List
<
CellRangeAddress
>
listCombineCell
,
Cell
cell
,
Sheet
sheet
)
{
int
xr
=
0
;
int
firstC
=
0
;
int
lastC
=
0
;
int
firstR
=
0
;
int
lastR
=
0
;
for
(
CellRangeAddress
ca
:
listCombineCell
)
{
//获得合并单元格的起始行, 结束行, 起始列, 结束列
firstC
=
ca
.
getFirstColumn
();
lastC
=
ca
.
getLastColumn
();
firstR
=
ca
.
getFirstRow
();
lastR
=
ca
.
getLastRow
();
if
(
cell
.
getRowIndex
()
>=
firstR
&&
cell
.
getRowIndex
()
<=
lastR
)
{
if
(
cell
.
getColumnIndex
()
>=
firstC
&&
cell
.
getColumnIndex
()
<=
lastC
)
{
xr
=
lastR
;
}
}
}
return
xr
;
}
/**
* 判断单元格是否为合并单元格,是的话则将单元格的值返回
*
* @param listCombineCell 存放合并单元格的list
* @param cell 需要判断的单元格
* @param sheet sheet
* @return
*/
public
String
isCombineCell
(
List
<
CellRangeAddress
>
listCombineCell
,
Cell
cell
,
Sheet
sheet
)
throws
Exception
{
int
firstC
=
0
;
int
lastC
=
0
;
int
firstR
=
0
;
int
lastR
=
0
;
String
cellValue
=
null
;
for
(
CellRangeAddress
ca
:
listCombineCell
)
{
//获得合并单元格的起始行, 结束行, 起始列, 结束列
firstC
=
ca
.
getFirstColumn
();
lastC
=
ca
.
getLastColumn
();
firstR
=
ca
.
getFirstRow
();
lastR
=
ca
.
getLastRow
();
if
(
cell
.
getRowIndex
()
>=
firstR
&&
cell
.
getRowIndex
()
<=
lastR
)
{
if
(
cell
.
getColumnIndex
()
>=
firstC
&&
cell
.
getColumnIndex
()
<=
lastC
)
{
Row
fRow
=
sheet
.
getRow
(
firstR
);
Cell
fCell
=
fRow
.
getCell
(
firstC
);
cellValue
=
getCellValue
(
fCell
);
break
;
}
}
else
{
cellValue
=
""
;
}
}
return
cellValue
;
}
/**
* 获取合并单元格的值
*
* @param sheet
* @param row
* @param column
* @return
*/
public
String
getMergedRegionValue
(
Sheet
sheet
,
int
row
,
int
column
)
{
int
sheetMergeCount
=
sheet
.
getNumMergedRegions
();
for
(
int
i
=
0
;
i
<
sheetMergeCount
;
i
++)
{
CellRangeAddress
ca
=
sheet
.
getMergedRegion
(
i
);
int
firstColumn
=
ca
.
getFirstColumn
();
int
lastColumn
=
ca
.
getLastColumn
();
int
firstRow
=
ca
.
getFirstRow
();
int
lastRow
=
ca
.
getLastRow
();
if
(
row
>=
firstRow
&&
row
<=
lastRow
)
{
if
(
column
>=
firstColumn
&&
column
<=
lastColumn
)
{
Row
fRow
=
sheet
.
getRow
(
firstRow
);
Cell
fCell
=
fRow
.
getCell
(
firstColumn
);
return
getCellValue
(
fCell
);
}
}
}
return
null
;
}
/**
* 判断指定的单元格是否是合并单元格
*
* @param sheet
* @param row 行下标
* @param column 列下标
* @return
*/
private
boolean
isMergedRegion
(
Sheet
sheet
,
int
row
,
int
column
)
{
int
sheetMergeCount
=
sheet
.
getNumMergedRegions
();
for
(
int
i
=
0
;
i
<
sheetMergeCount
;
i
++)
{
CellRangeAddress
range
=
sheet
.
getMergedRegion
(
i
);
int
firstColumn
=
range
.
getFirstColumn
();
int
lastColumn
=
range
.
getLastColumn
();
int
firstRow
=
range
.
getFirstRow
();
int
lastRow
=
range
.
getLastRow
();
if
(
row
>=
firstRow
&&
row
<=
lastRow
)
{
if
(
column
>=
firstColumn
&&
column
<=
lastColumn
)
{
return
true
;
}
}
}
return
false
;
}
}
\ No newline at end of file
\ No newline at end of file
nafmii-admin/src/main/resources/mapper/ImportExcelMapper.xml
0 → 100644
View file @
1170aa2
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"org.nafmii.admin.user.dao.ImportExcelMapper"
>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"org.nafmii.admin.user.entity.ImportExcelPO"
>
<result
column=
"COLUMN1"
property=
"column1"
/>
<result
column=
"COLUMN2"
property=
"column2"
/>
<result
column=
"COLUMN3"
property=
"column3"
/>
</resultMap>
<insert
id =
"insertExcelData"
parameterType=
"org.nafmii.admin.user.dto.ImportExcelDto"
>
insert into IMPORT_EXCEL_TEST
(COLUMN1,COLUMN2,COLUMN3)
values(#{column1},
#{column2},
#{column3})
</insert >
</mapper>
nafmii-common/pom.xml
View file @
1170aa2
...
@@ -154,24 +154,23 @@
...
@@ -154,24 +154,23 @@
<dependency>
<dependency>
<groupId>
org.apache.poi
</groupId>
<groupId>
org.apache.poi
</groupId>
<artifactId>
poi
</artifactId>
<artifactId>
poi
</artifactId>
<version>
3.
9
</version>
<version>
3.
17
</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
org.apache.poi
</groupId>
<groupId>
org.apache.poi
</groupId>
<artifactId>
poi-ooxml
</artifactId>
<artifactId>
poi-ooxml
</artifactId>
<version>
3.9
</version>
<version>
3.17
</version>
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
easyexcel
</artifactId>
<version>
2.1.6
</version>
</dependency>
</dependency>
<dependency>
<dependency>
<groupId>
javax.cache
</groupId>
<groupId>
javax.cache
</groupId>
<artifactId>
cache-api
</artifactId>
<artifactId>
cache-api
</artifactId>
<version>
1.1.0
</version>
<version>
1.1.0
</version>
</dependency>
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
easyexcel
</artifactId>
<version>
2.1.6
</version>
</dependency>
<dependency>
<dependency>
<groupId>
com.google.guava
</groupId>
<groupId>
com.google.guava
</groupId>
<artifactId>
guava
</artifactId>
<artifactId>
guava
</artifactId>
...
@@ -181,7 +180,7 @@
...
@@ -181,7 +180,7 @@
<dependency>
<dependency>
<groupId>
org.apache.poi
</groupId>
<groupId>
org.apache.poi
</groupId>
<artifactId>
poi-ooxml-schemas
</artifactId>
<artifactId>
poi-ooxml-schemas
</artifactId>
<version>
3.
9
</version>
<version>
3.
17
</version>
</dependency>
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<dependency>
...
...
nafmii-common/src/main/java/org/nafmii/common/excle/Reflections.java
deleted
100644 → 0
View file @
62a3146
package
org
.
nafmii
.
common
.
excle
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.Validate
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.util.Assert
;
import
java.lang.reflect.*
;
/**
* 反射工具类.
* 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*
* @author calvin
* @version 2013-01-15
*/
@SuppressWarnings
(
"rawtypes"
)
public
class
Reflections
{
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
(
Reflections
.
class
);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
public
static
Object
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
object
;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public
static
void
invokeSetter
(
Object
obj
,
String
propertyName
,
Object
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函数.
*/
public
static
Object
getFieldValue
(
final
Object
obj
,
final
String
fieldName
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
throw
new
IllegalArgumentException
(
"Could not find field ["
+
fieldName
+
"] on target ["
+
obj
+
"]"
);
}
Object
result
=
null
;
try
{
result
=
field
.
get
(
obj
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常{}"
,
e
.
getMessage
());
}
return
result
;
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public
static
void
setFieldValue
(
final
Object
obj
,
final
String
fieldName
,
final
Object
value
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
throw
new
IllegalArgumentException
(
"Could not find field ["
+
fieldName
+
"] on target ["
+
obj
+
"]"
);
}
try
{
field
.
set
(
obj
,
value
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常:{}"
,
e
.
getMessage
());
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
public
static
Object
invokeMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>[]
parameterTypes
,
final
Object
[]
args
)
{
Method
method
=
getAccessibleMethod
(
obj
,
methodName
,
parameterTypes
);
if
(
method
==
null
)
{
throw
new
IllegalArgumentException
(
"Could not find method ["
+
methodName
+
"] on target ["
+
obj
+
"]"
);
}
try
{
return
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
throw
convertReflectionExceptionToUnchecked
(
e
);
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
public
static
Object
invokeMethodByName
(
final
Object
obj
,
final
String
methodName
,
final
Object
[]
args
)
{
Method
method
=
getAccessibleMethodByName
(
obj
,
methodName
);
if
(
method
==
null
)
{
throw
new
IllegalArgumentException
(
"Could not find method ["
+
methodName
+
"] on target ["
+
obj
+
"]"
);
}
try
{
return
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
throw
convertReflectionExceptionToUnchecked
(
e
);
}
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* <p>
* 如向上转型到Object仍无法找到, 返回null.
*/
public
static
Field
getAccessibleField
(
final
Object
obj
,
final
String
fieldName
)
{
Validate
.
notNull
(
obj
,
"object can't be 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
)
{
//NOSONAR
// Field不在当前类定义,继续向上转型
continue
;
// new add
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 匹配函数名+参数类型。
* <p>
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>...
parameterTypes
)
{
Validate
.
notNull
(
obj
,
"object can't be 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
)
{
// Method不在当前类定义,继续向上转型
continue
;
// new add
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 只匹配函数名。
* <p>
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethodByName
(
final
Object
obj
,
final
String
methodName
)
{
Validate
.
notNull
(
obj
,
"object can't be 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
))
{
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.
* eg.
* public UserDao extends HibernateDao<User>
*
* @param clazz The class to introspect
* @return the first generic declaration, or Object.class if cannot be determined
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
Class
<
T
>
getClassGenricType
(
final
Class
clazz
)
{
return
getClassGenricType
(
clazz
,
0
);
}
/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
* <p>
* 如public UserDao extends HibernateDao<User,Long>
*
* @param clazz clazz The class to introspect
* @param index the Index of the generic ddeclaration,start from 0.
* @return the index generic declaration, or Object.class if cannot be determined
*/
public
static
Class
getClassGenricType
(
final
Class
clazz
,
final
int
index
)
{
Type
genType
=
clazz
.
getGenericSuperclass
();
if
(!(
genType
instanceof
ParameterizedType
))
{
logger
.
warn
(
clazz
.
getSimpleName
()
+
"'s superclass not ParameterizedType"
);
return
Object
.
class
;
}
Type
[]
params
=
((
ParameterizedType
)
genType
).
getActualTypeArguments
();
if
(
index
>=
params
.
length
||
index
<
0
)
{
logger
.
warn
(
"Index: "
+
index
+
", Size of "
+
clazz
.
getSimpleName
()
+
"'s Parameterized Type: "
+
params
.
length
);
return
Object
.
class
;
}
if
(!(
params
[
index
]
instanceof
Class
))
{
logger
.
warn
(
clazz
.
getSimpleName
()
+
" not set the actual class on superclass generic parameter"
);
return
Object
.
class
;
}
return
(
Class
)
params
[
index
];
}
public
static
Class
<?>
getUserClass
(
Object
instance
)
{
Assert
.
notNull
(
instance
,
"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
(
Exception
e
)
{
if
(
e
instanceof
IllegalAccessException
||
e
instanceof
IllegalArgumentException
||
e
instanceof
NoSuchMethodException
)
{
return
new
IllegalArgumentException
(
e
);
}
else
if
(
e
instanceof
InvocationTargetException
)
{
return
new
RuntimeException
(((
InvocationTargetException
)
e
).
getTargetException
());
}
else
if
(
e
instanceof
RuntimeException
)
{
return
(
RuntimeException
)
e
;
}
return
new
RuntimeException
(
"Unexpected Checked Exception."
,
e
);
}
}
nafmii-common/src/main/java/org/nafmii/common/excle/annotation/ExcelField.java
deleted
100644 → 0
View file @
62a3146
package
org
.
nafmii
.
common
.
excle
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Excel注解定义
* Created by tianc on 17/8/25.
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
FIELD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ExcelField
{
/**
* 导出字段名(默认调用当前字段的“get”方法,如指定导出字段为对象,请填写“对象名.对象属性”,例:“area.name”、“office.name”)
*/
String
value
()
default
""
;
/**
* 导出字段标题(需要添加批注请用“**”分隔,标题**批注,仅对导出模板有效)
*/
String
title
();
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
int
type
()
default
0
;
/**
* 导出字段对齐方式(0:自动;1:靠左;2:居中;3:靠右)
*/
int
align
()
default
0
;
/**
* 导出字段字段排序(升序)
*/
int
sort
()
default
0
;
/**
* 如果是字典类型,请设置字典的type值
*/
String
dictType
()
default
""
;
/**
* 反射类型
*/
Class
<?>
fieldType
()
default
Class
.
class
;
/**
* 字段归属组(根据分组导出导入)
*/
int
[]
groups
()
default
{};
}
nafmii-common/src/main/java/org/nafmii/common/excle/test.java
deleted
100644 → 0
View file @
62a3146
package
org
.
nafmii
.
common
.
excle
;
/**
* @author:zhoujh
* @Function:TODO
* @date 2021/4/29 15:35
* @ClassName:
* @version:
* @remark:
*/
public
class
test
{
}
nafmii-common/src/main/java/org/nafmii/common/utils/ImportExcelUtils.java
deleted
100644 → 0
View file @
62a3146
package
org
.
nafmii
.
common
.
utils
;
import
com.google.common.collect.Lists
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.poi.hssf.usermodel.HSSFWorkbook
;
import
org.apache.poi.openxml4j.exceptions.InvalidFormatException
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
org.nafmii.common.excle.Reflections
;
import
org.nafmii.common.excle.annotation.ExcelField
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Date
;
import
java.util.List
;
/**
* 导入Excel文件(支持“XLS”和“XLS”格式)
* Created by tianc on 17/8/25.
*/
public
class
ImportExcelUtils
{
private
static
Logger
log
=
LoggerFactory
.
getLogger
(
ImportExcelUtils
.
class
);
/**
* 工作薄对象
*/
private
Workbook
wb
;
/**
* 工作表对象
*/
private
Sheet
sheet
;
/**
* 标题行号
*/
private
int
headerNum
;
/**
* 构造函数
*
* @param fileName 导入文件,读取第一个工作表
* @param headerNum 标题行号,数据行号=标题行号+1
* @throws InvalidFormatException
* @throws IOException
*/
public
ImportExcelUtils
(
String
fileName
,
int
headerNum
)
throws
InvalidFormatException
,
IOException
{
this
(
new
File
(
fileName
),
headerNum
);
}
/**
* 构造函数
*
* @param file 导入文件对象,读取第一个工作表
* @param headerNum 标题行号,数据行号=标题行号+1
* @throws InvalidFormatException
* @throws IOException
*/
public
ImportExcelUtils
(
File
file
,
int
headerNum
)
throws
InvalidFormatException
,
IOException
{
this
(
file
,
headerNum
,
0
);
}
/**
* 构造函数
*
* @param fileName 导入文件
* @param headerNum 标题行号,数据行号=标题行号+1
* @param sheetIndex 工作表编号
* @throws InvalidFormatException
* @throws IOException
*/
public
ImportExcelUtils
(
String
fileName
,
int
headerNum
,
int
sheetIndex
)
throws
InvalidFormatException
,
IOException
{
this
(
new
File
(
fileName
),
headerNum
,
sheetIndex
);
}
/**
* 构造函数
*
* @param file 导入文件对象
* @param headerNum 标题行号,数据行号=标题行号+1
* @param sheetIndex 工作表编号
* @throws InvalidFormatException
* @throws IOException
*/
public
ImportExcelUtils
(
File
file
,
int
headerNum
,
int
sheetIndex
)
throws
InvalidFormatException
,
IOException
{
this
(
file
.
getName
(),
new
FileInputStream
(
file
),
headerNum
,
sheetIndex
);
}
/**
* 构造函数
*
* @param multipartFile 导入文件对象
* @param headerNum 标题行号,数据行号=标题行号+1
* @param sheetIndex 工作表编号
* @throws InvalidFormatException
* @throws IOException
*/
public
ImportExcelUtils
(
MultipartFile
multipartFile
,
int
headerNum
,
int
sheetIndex
)
throws
InvalidFormatException
,
IOException
{
this
(
multipartFile
.
getOriginalFilename
(),
multipartFile
.
getInputStream
(),
headerNum
,
sheetIndex
);
}
/**
* 构造函数
*
* @param fileName 导入文件对象
* @param headerNum 标题行号,数据行号=标题行号+1
* @param sheetIndex 工作表编号
* @throws InvalidFormatException
* @throws IOException
*/
public
ImportExcelUtils
(
String
fileName
,
InputStream
is
,
int
headerNum
,
int
sheetIndex
)
throws
InvalidFormatException
,
IOException
{
try
{
if
(
fileName
==
null
||
fileName
==
""
)
{
throw
new
RuntimeException
(
"导入文档为空!"
);
}
else
if
(
fileName
.
toLowerCase
().
endsWith
(
"xls"
))
{
this
.
wb
=
new
HSSFWorkbook
(
is
);
}
else
if
(
fileName
.
toLowerCase
().
endsWith
(
"xlsx"
))
{
this
.
wb
=
new
XSSFWorkbook
(
is
);
}
else
{
throw
new
RuntimeException
(
"文档格式不正确!"
);
}
if
(
this
.
wb
.
getNumberOfSheets
()
<
sheetIndex
)
{
throw
new
RuntimeException
(
"文档中没有工作表!"
);
}
this
.
sheet
=
this
.
wb
.
getSheetAt
(
sheetIndex
);
this
.
headerNum
=
headerNum
;
log
.
debug
(
"Initialize success."
);
}
finally
{
is
.
close
();
}
}
/**
* 获取行对象
*
* @param rownum
* @return
*/
public
Row
getRow
(
int
rownum
)
{
return
this
.
sheet
.
getRow
(
rownum
);
}
/**
* 获取数据行号
*
* @return
*/
public
int
getDataRowNum
()
{
return
headerNum
+
1
;
}
/**
* 获取最后一个数据行号
*
* @return
*/
public
int
getLastDataRowNum
()
{
return
this
.
sheet
.
getLastRowNum
()
+
headerNum
;
}
/**
* 获取最后一个列号
*
* @return
*/
public
int
getLastCellNum
()
{
return
this
.
getRow
(
headerNum
).
getLastCellNum
();
}
/**
* 获取单元格值
*
* @param row 获取的行
* @param column 获取单元格列号
* @return 单元格值
*/
public
Object
getCellValue
(
Row
row
,
int
column
)
{
Object
val
=
""
;
try
{
Cell
cell
=
row
.
getCell
(
column
);
if
(
cell
!=
null
)
{
if
(
cell
.
getCellType
()
==
Cell
.
CELL_TYPE_NUMERIC
)
{
val
=
cell
.
getNumericCellValue
();
}
else
if
(
cell
.
getCellType
()
==
Cell
.
CELL_TYPE_STRING
)
{
val
=
cell
.
getStringCellValue
();
}
else
if
(
cell
.
getCellType
()
==
Cell
.
CELL_TYPE_FORMULA
)
{
val
=
cell
.
getCellFormula
();
}
else
if
(
cell
.
getCellType
()
==
Cell
.
CELL_TYPE_BOOLEAN
)
{
val
=
cell
.
getBooleanCellValue
();
}
else
if
(
cell
.
getCellType
()
==
Cell
.
CELL_TYPE_ERROR
)
{
val
=
cell
.
getErrorCellValue
();
}
}
}
catch
(
Exception
e
)
{
return
val
;
}
return
val
;
}
/**
* 获取导入数据列表
*
* @param cls 导入对象类型
* @param groups 导入分组
*/
public
<
E
>
List
<
E
>
getDataList
(
Class
<
E
>
cls
,
int
...
groups
)
throws
InstantiationException
,
IllegalAccessException
{
List
<
Object
[]>
annotationList
=
Lists
.
newArrayList
();
// Get annotation field
Field
[]
fs
=
cls
.
getDeclaredFields
();
for
(
Field
f
:
fs
)
{
ExcelField
ef
=
f
.
getAnnotation
(
ExcelField
.
class
);
if
(
ef
!=
null
&&
(
ef
.
type
()
==
0
||
ef
.
type
()
==
2
))
{
if
(
groups
!=
null
&&
groups
.
length
>
0
)
{
boolean
inGroup
=
false
;
for
(
int
g
:
groups
)
{
if
(
inGroup
)
{
break
;
}
for
(
int
efg
:
ef
.
groups
())
{
if
(
g
==
efg
)
{
inGroup
=
true
;
annotationList
.
add
(
new
Object
[]{
ef
,
f
});
break
;
}
}
}
}
else
{
annotationList
.
add
(
new
Object
[]{
ef
,
f
});
}
}
}
// Get annotation method
Method
[]
ms
=
cls
.
getDeclaredMethods
();
for
(
Method
m
:
ms
)
{
ExcelField
ef
=
m
.
getAnnotation
(
ExcelField
.
class
);
if
(
ef
!=
null
&&
(
ef
.
type
()
==
0
||
ef
.
type
()
==
2
))
{
if
(
groups
!=
null
&&
groups
.
length
>
0
)
{
boolean
inGroup
=
false
;
for
(
int
g
:
groups
)
{
if
(
inGroup
)
{
break
;
}
for
(
int
efg
:
ef
.
groups
())
{
if
(
g
==
efg
)
{
inGroup
=
true
;
annotationList
.
add
(
new
Object
[]{
ef
,
m
});
break
;
}
}
}
}
else
{
annotationList
.
add
(
new
Object
[]{
ef
,
m
});
}
}
}
// Field sorting
Collections
.
sort
(
annotationList
,
new
Comparator
<
Object
[]>()
{
public
int
compare
(
Object
[]
o1
,
Object
[]
o2
)
{
return
new
Integer
(((
ExcelField
)
o1
[
0
]).
sort
()).
compareTo
(
new
Integer
(((
ExcelField
)
o2
[
0
]).
sort
()));
}
});
//log.debug("Import column count:"+annotationList.size());
// Get excel data
List
<
E
>
dataList
=
Lists
.
newArrayList
();
for
(
int
i
=
this
.
getDataRowNum
();
i
<
this
.
getLastDataRowNum
();
i
++)
{
E
e
=
cls
.
newInstance
();
int
column
=
0
;
Row
row
=
this
.
getRow
(
i
);
StringBuilder
sb
=
new
StringBuilder
();
for
(
Object
[]
os
:
annotationList
)
{
Object
val
=
this
.
getCellValue
(
row
,
column
++);
if
(
val
!=
null
)
{
ExcelField
ef
=
(
ExcelField
)
os
[
0
];
// If is dict type, get dict value
// if (StringUtils.isNotBlank(ef.dictType())) {
// val = DictUtils.getDictValue(val.toString(), ef.dictType(), "");
// }
// Get param type and type cast
Class
<?>
valType
=
Class
.
class
;
if
(
os
[
1
]
instanceof
Field
)
{
valType
=
((
Field
)
os
[
1
]).
getType
();
}
else
if
(
os
[
1
]
instanceof
Method
)
{
Method
method
=
((
Method
)
os
[
1
]);
if
(
"get"
.
equals
(
method
.
getName
().
substring
(
0
,
3
)))
{
valType
=
method
.
getReturnType
();
}
else
if
(
"set"
.
equals
(
method
.
getName
().
substring
(
0
,
3
)))
{
valType
=
((
Method
)
os
[
1
]).
getParameterTypes
()[
0
];
}
}
//log.debug("Import value type: ["+i+","+column+"] " + valType);
try
{
if
(
valType
==
String
.
class
)
{
String
s
=
String
.
valueOf
(
val
.
toString
());
if
(
s
.
endsWith
(
".0"
))
{
val
=
StringUtils
.
substringBefore
(
s
,
".0"
);
}
else
{
val
=
String
.
valueOf
(
val
.
toString
());
}
}
else
if
(
valType
==
Integer
.
class
)
{
val
=
Double
.
valueOf
(
val
.
toString
()).
intValue
();
}
else
if
(
valType
==
Long
.
class
)
{
val
=
Double
.
valueOf
(
val
.
toString
()).
longValue
();
}
else
if
(
valType
==
Double
.
class
)
{
val
=
Double
.
valueOf
(
val
.
toString
());
}
else
if
(
valType
==
Float
.
class
)
{
val
=
Float
.
valueOf
(
val
.
toString
());
}
else
if
(
valType
==
Date
.
class
)
{
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
}
else
{
if
(
ef
.
fieldType
()
!=
Class
.
class
)
{
val
=
ef
.
fieldType
().
getMethod
(
"getValue"
,
String
.
class
).
invoke
(
null
,
val
.
toString
());
}
else
{
val
=
Class
.
forName
(
this
.
getClass
().
getName
().
replaceAll
(
this
.
getClass
().
getSimpleName
(),
"fieldtype."
+
valType
.
getSimpleName
()
+
"Type"
)).
getMethod
(
"getValue"
,
String
.
class
).
invoke
(
null
,
val
.
toString
());
}
}
}
catch
(
Exception
ex
)
{
log
.
info
(
"Get cell value ["
+
i
+
","
+
column
+
"] error: "
+
ex
.
toString
());
val
=
null
;
}
// set entity value
if
(
os
[
1
]
instanceof
Field
)
{
Reflections
.
invokeSetter
(
e
,
((
Field
)
os
[
1
]).
getName
(),
val
);
}
else
if
(
os
[
1
]
instanceof
Method
)
{
String
mthodName
=
((
Method
)
os
[
1
]).
getName
();
if
(
"get"
.
equals
(
mthodName
.
substring
(
0
,
3
)))
{
mthodName
=
"set"
+
StringUtils
.
substringAfter
(
mthodName
,
"get"
);
}
Reflections
.
invokeMethod
(
e
,
mthodName
,
new
Class
[]{
valType
},
new
Object
[]{
val
});
}
}
sb
.
append
(
val
+
", "
);
}
dataList
.
add
(
e
);
log
.
debug
(
"Read success: ["
+
i
+
"] "
+
sb
.
toString
());
}
return
dataList
;
}
/**
* 导入测试
*/
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
// File file = new File("D:\\excle");
// if (!file.exists()){
// file.getParentFile().mkdir();
// }
ImportExcelUtils
ei
=
new
ImportExcelUtils
(
"D:\\excle/test1.xlsx"
,
1
);
for
(
int
i
=
ei
.
getDataRowNum
();
i
<
ei
.
getLastDataRowNum
();
i
++)
{
Row
row
=
ei
.
getRow
(
i
);
for
(
int
j
=
0
;
j
<
ei
.
getLastCellNum
();
j
++)
{
Object
val
=
ei
.
getCellValue
(
row
,
j
);
System
.
out
.
print
(
val
+
", "
);
}
System
.
out
.
print
(
"\n"
);
}
}
}
Write
Preview
Markdown
is supported
Attach a file
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 post a comment