Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
finance-manage
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
finance-oa
finance-manage
Commits
e73dbd47
Commit
e73dbd47
authored
Aug 07, 2022
by
RuoYi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Excel注解支持导出对象的子列表方法
parent
e0cd5381
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
202 additions
and
25 deletions
+202
-25
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java
...mmon/src/main/java/com/ruoyi/common/annotation/Excel.java
+6
-17
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
...n/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
+196
-8
No files found.
ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java
View file @
e73dbd47
...
@@ -88,6 +88,11 @@ public @interface Excel
...
@@ -88,6 +88,11 @@ public @interface Excel
*/
*/
public
String
[]
combo
()
default
{};
public
String
[]
combo
()
default
{};
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public
boolean
needMerge
()
default
false
;
/**
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
*/
...
@@ -104,7 +109,7 @@ public @interface Excel
...
@@ -104,7 +109,7 @@ public @interface Excel
public
boolean
isStatistics
()
default
false
;
public
boolean
isStatistics
()
default
false
;
/**
/**
* 导出类型(0数字 1字符串)
* 导出类型(0数字 1字符串
2图片
)
*/
*/
public
ColumnType
cellType
()
default
ColumnType
.
STRING
;
public
ColumnType
cellType
()
default
ColumnType
.
STRING
;
...
@@ -143,22 +148,6 @@ public @interface Excel
...
@@ -143,22 +148,6 @@ public @interface Excel
*/
*/
public
String
[]
args
()
default
{};
public
String
[]
args
()
default
{};
public
enum
Align
{
AUTO
(
0
),
LEFT
(
1
),
CENTER
(
2
),
RIGHT
(
3
);
private
final
int
value
;
Align
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
return
this
.
value
;
}
}
/**
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
*/
...
...
ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
View file @
e73dbd47
...
@@ -7,12 +7,14 @@ import java.io.InputStream;
...
@@ -7,12 +7,14 @@ import java.io.InputStream;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.ParameterizedType
;
import
java.math.BigDecimal
;
import
java.math.BigDecimal
;
import
java.text.DecimalFormat
;
import
java.text.DecimalFormat
;
import
java.time.LocalDate
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Comparator
;
import
java.util.Comparator
;
import
java.util.Date
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -24,6 +26,7 @@ import java.util.stream.Collectors;
...
@@ -24,6 +26,7 @@ import java.util.stream.Collectors;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpServletResponse
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.commons.lang3.reflect.FieldUtils
;
import
org.apache.poi.hssf.usermodel.HSSFClientAnchor
;
import
org.apache.poi.hssf.usermodel.HSSFClientAnchor
;
import
org.apache.poi.hssf.usermodel.HSSFPicture
;
import
org.apache.poi.hssf.usermodel.HSSFPicture
;
import
org.apache.poi.hssf.usermodel.HSSFPictureData
;
import
org.apache.poi.hssf.usermodel.HSSFPictureData
;
...
@@ -149,6 +152,26 @@ public class ExcelUtil<T>
...
@@ -149,6 +152,26 @@ public class ExcelUtil<T>
*/
*/
private
short
maxHeight
;
private
short
maxHeight
;
/**
* 合并后最后行数
*/
private
int
subMergedLastRowNum
=
0
;
/**
* 合并后开始行数
*/
private
int
subMergedFirstRowNum
=
1
;
/**
* 对象的子列表方法
*/
private
Method
subMethod
;
/**
* 对象的子列表属性
*/
private
List
<
Field
>
subFields
;
/**
/**
* 统计列表
* 统计列表
*/
*/
...
@@ -198,6 +221,7 @@ public class ExcelUtil<T>
...
@@ -198,6 +221,7 @@ public class ExcelUtil<T>
createExcelField
();
createExcelField
();
createWorkbook
();
createWorkbook
();
createTitle
();
createTitle
();
createSubHead
();
}
}
/**
/**
...
@@ -207,13 +231,48 @@ public class ExcelUtil<T>
...
@@ -207,13 +231,48 @@ public class ExcelUtil<T>
{
{
if
(
StringUtils
.
isNotEmpty
(
title
))
if
(
StringUtils
.
isNotEmpty
(
title
))
{
{
subMergedFirstRowNum
++;
subMergedLastRowNum
++;
int
titleLastCol
=
this
.
fields
.
size
()
-
1
;
if
(
isSubList
())
{
titleLastCol
=
titleLastCol
+
subFields
.
size
()
-
1
;
}
Row
titleRow
=
sheet
.
createRow
(
rownum
==
0
?
rownum
++
:
0
);
Row
titleRow
=
sheet
.
createRow
(
rownum
==
0
?
rownum
++
:
0
);
titleRow
.
setHeightInPoints
(
30
);
titleRow
.
setHeightInPoints
(
30
);
Cell
titleCell
=
titleRow
.
createCell
(
0
);
Cell
titleCell
=
titleRow
.
createCell
(
0
);
titleCell
.
setCellStyle
(
styles
.
get
(
"title"
));
titleCell
.
setCellStyle
(
styles
.
get
(
"title"
));
titleCell
.
setCellValue
(
title
);
titleCell
.
setCellValue
(
title
);
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
titleLastCol
));
this
.
fields
.
size
()
-
1
));
}
}
/**
* 创建对象的子列表名称
*/
public
void
createSubHead
()
{
if
(
isSubList
())
{
subMergedFirstRowNum
++;
subMergedLastRowNum
++;
Row
subRow
=
sheet
.
createRow
(
rownum
);
int
excelNum
=
0
;
for
(
Object
[]
objects
:
fields
)
{
Excel
attr
=
(
Excel
)
objects
[
1
];
Cell
headCell1
=
subRow
.
createCell
(
excelNum
);
headCell1
.
setCellValue
(
attr
.
name
());
headCell1
.
setCellStyle
(
styles
.
get
(
StringUtils
.
format
(
"header_{}_{}"
,
attr
.
headerColor
(),
attr
.
headerBackgroundColor
())));
excelNum
++;
}
int
headFirstRow
=
excelNum
-
1
;
int
headLastRow
=
headFirstRow
+
subFields
.
size
()
-
1
;
if
(
headLastRow
>
headFirstRow
)
{
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
rownum
,
rownum
,
headFirstRow
,
headLastRow
));
}
rownum
++;
}
}
}
}
...
@@ -593,8 +652,20 @@ public class ExcelUtil<T>
...
@@ -593,8 +652,20 @@ public class ExcelUtil<T>
// 写入各个字段的列头名称
// 写入各个字段的列头名称
for
(
Object
[]
os
:
fields
)
for
(
Object
[]
os
:
fields
)
{
{
Field
field
=
(
Field
)
os
[
0
];
Excel
excel
=
(
Excel
)
os
[
1
];
Excel
excel
=
(
Excel
)
os
[
1
];
this
.
createCell
(
excel
,
row
,
column
++);
if
(
Collection
.
class
.
isAssignableFrom
(
field
.
getType
()))
{
for
(
Field
subField
:
subFields
)
{
Excel
subExcel
=
subField
.
getAnnotation
(
Excel
.
class
);
this
.
createHeadCell
(
subExcel
,
row
,
column
++);
}
}
else
{
this
.
createHeadCell
(
excel
,
row
,
column
++);
}
}
}
if
(
Type
.
EXPORT
.
equals
(
type
))
if
(
Type
.
EXPORT
.
equals
(
type
))
{
{
...
@@ -610,24 +681,63 @@ public class ExcelUtil<T>
...
@@ -610,24 +681,63 @@ public class ExcelUtil<T>
* @param index 序号
* @param index 序号
* @param row 单元格行
* @param row 单元格行
*/
*/
@SuppressWarnings
(
"unchecked"
)
public
void
fillExcelData
(
int
index
,
Row
row
)
public
void
fillExcelData
(
int
index
,
Row
row
)
{
{
int
startNo
=
index
*
sheetSize
;
int
startNo
=
index
*
sheetSize
;
int
endNo
=
Math
.
min
(
startNo
+
sheetSize
,
list
.
size
());
int
endNo
=
Math
.
min
(
startNo
+
sheetSize
,
list
.
size
());
int
rowNo
=
(
1
+
rownum
)
-
startNo
;
for
(
int
i
=
startNo
;
i
<
endNo
;
i
++)
for
(
int
i
=
startNo
;
i
<
endNo
;
i
++)
{
{
row
=
sheet
.
createRow
(
i
+
1
+
rownum
-
startNo
);
rowNo
=
i
>
1
?
rowNo
+
1
:
rowNo
+
i
;
row
=
sheet
.
createRow
(
rowNo
);
// 得到导出对象.
// 得到导出对象.
T
vo
=
(
T
)
list
.
get
(
i
);
T
vo
=
(
T
)
list
.
get
(
i
);
Collection
<?>
subList
=
null
;
if
(
isSubListValue
(
vo
))
{
subList
=
getListCellValue
(
vo
);
subMergedLastRowNum
=
subMergedLastRowNum
+
subList
.
size
();
}
int
column
=
0
;
int
column
=
0
;
for
(
Object
[]
os
:
fields
)
for
(
Object
[]
os
:
fields
)
{
{
Field
field
=
(
Field
)
os
[
0
];
Field
field
=
(
Field
)
os
[
0
];
Excel
excel
=
(
Excel
)
os
[
1
];
Excel
excel
=
(
Excel
)
os
[
1
];
if
(
Collection
.
class
.
isAssignableFrom
(
field
.
getType
())
&&
StringUtils
.
isNotNull
(
subList
))
{
boolean
subFirst
=
false
;
for
(
Object
obj
:
subList
)
{
if
(
subFirst
)
{
rowNo
++;
row
=
sheet
.
createRow
(
rowNo
);
}
List
<
Field
>
subFields
=
FieldUtils
.
getFieldsListWithAnnotation
(
obj
.
getClass
(),
Excel
.
class
);
int
subIndex
=
0
;
for
(
Field
subField
:
subFields
)
{
if
(
subField
.
isAnnotationPresent
(
Excel
.
class
))
{
subField
.
setAccessible
(
true
);
Excel
attr
=
subField
.
getAnnotation
(
Excel
.
class
);
this
.
addCell
(
attr
,
row
,
(
T
)
obj
,
subField
,
column
+
subIndex
);
}
subIndex
++;
}
subFirst
=
true
;
}
this
.
subMergedFirstRowNum
=
this
.
subMergedFirstRowNum
+
subList
.
size
();
}
else
{
this
.
addCell
(
excel
,
row
,
vo
,
field
,
column
++);
this
.
addCell
(
excel
,
row
,
vo
,
field
,
column
++);
}
}
}
}
}
}
}
/**
/**
* 创建表格样式
* 创建表格样式
...
@@ -759,7 +869,7 @@ public class ExcelUtil<T>
...
@@ -759,7 +869,7 @@ public class ExcelUtil<T>
/**
/**
* 创建单元格
* 创建单元格
*/
*/
public
Cell
createCell
(
Excel
attr
,
Row
row
,
int
column
)
public
Cell
create
Head
Cell
(
Excel
attr
,
Row
row
,
int
column
)
{
{
// 创建列
// 创建列
Cell
cell
=
row
.
createCell
(
column
);
Cell
cell
=
row
.
createCell
(
column
);
...
@@ -767,6 +877,15 @@ public class ExcelUtil<T>
...
@@ -767,6 +877,15 @@ public class ExcelUtil<T>
cell
.
setCellValue
(
attr
.
name
());
cell
.
setCellValue
(
attr
.
name
());
setDataValidation
(
attr
,
row
,
column
);
setDataValidation
(
attr
,
row
,
column
);
cell
.
setCellStyle
(
styles
.
get
(
StringUtils
.
format
(
"header_{}_{}"
,
attr
.
headerColor
(),
attr
.
headerBackgroundColor
())));
cell
.
setCellStyle
(
styles
.
get
(
StringUtils
.
format
(
"header_{}_{}"
,
attr
.
headerColor
(),
attr
.
headerBackgroundColor
())));
if
(
isSubList
())
{
// 填充默认样式,防止合并单元格样式失效
sheet
.
setDefaultColumnStyle
(
column
,
styles
.
get
(
StringUtils
.
format
(
"data_{}_{}_{}"
,
attr
.
align
(),
attr
.
color
(),
attr
.
backgroundColor
())));
if
(
attr
.
needMerge
())
{
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
rownum
-
1
,
rownum
,
column
,
column
));
}
}
return
cell
;
return
cell
;
}
}
...
@@ -874,6 +993,11 @@ public class ExcelUtil<T>
...
@@ -874,6 +993,11 @@ public class ExcelUtil<T>
{
{
// 创建cell
// 创建cell
cell
=
row
.
createCell
(
column
);
cell
=
row
.
createCell
(
column
);
if
(
isSubListValue
(
vo
)
&&
attr
.
needMerge
())
{
CellRangeAddress
cellAddress
=
new
CellRangeAddress
(
subMergedFirstRowNum
,
subMergedLastRowNum
,
column
,
column
);
sheet
.
addMergedRegion
(
cellAddress
);
}
cell
.
setCellStyle
(
styles
.
get
(
StringUtils
.
format
(
"data_{}_{}_{}"
,
attr
.
align
(),
attr
.
color
(),
attr
.
backgroundColor
())));
cell
.
setCellStyle
(
styles
.
get
(
StringUtils
.
format
(
"data_{}_{}_{}"
,
attr
.
align
(),
attr
.
color
(),
attr
.
backgroundColor
())));
// 用于读取对象中的属性
// 用于读取对象中的属性
...
@@ -969,7 +1093,7 @@ public class ExcelUtil<T>
...
@@ -969,7 +1093,7 @@ public class ExcelUtil<T>
for
(
String
item
:
convertSource
)
for
(
String
item
:
convertSource
)
{
{
String
[]
itemArray
=
item
.
split
(
"="
);
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
StringUtils
.
containsAny
(
separator
,
propertyValue
))
if
(
StringUtils
.
containsAny
(
propertyValue
,
separator
))
{
{
for
(
String
value
:
propertyValue
.
split
(
separator
))
for
(
String
value
:
propertyValue
.
split
(
separator
))
{
{
...
@@ -1006,7 +1130,7 @@ public class ExcelUtil<T>
...
@@ -1006,7 +1130,7 @@ public class ExcelUtil<T>
for
(
String
item
:
convertSource
)
for
(
String
item
:
convertSource
)
{
{
String
[]
itemArray
=
item
.
split
(
"="
);
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
StringUtils
.
containsAny
(
separator
,
propertyValue
))
if
(
StringUtils
.
containsAny
(
propertyValue
,
separator
))
{
{
for
(
String
value
:
propertyValue
.
split
(
separator
))
for
(
String
value
:
propertyValue
.
split
(
separator
))
{
{
...
@@ -1230,6 +1354,13 @@ public class ExcelUtil<T>
...
@@ -1230,6 +1354,13 @@ public class ExcelUtil<T>
field
.
setAccessible
(
true
);
field
.
setAccessible
(
true
);
fields
.
add
(
new
Object
[]
{
field
,
attr
});
fields
.
add
(
new
Object
[]
{
field
,
attr
});
}
}
if
(
Collection
.
class
.
isAssignableFrom
(
field
.
getType
()))
{
subMethod
=
getSubMethod
(
field
.
getName
(),
clazz
);
ParameterizedType
pt
=
(
ParameterizedType
)
field
.
getGenericType
();
Class
<?>
subClass
=
(
Class
<?>)
pt
.
getActualTypeArguments
()[
0
];
this
.
subFields
=
FieldUtils
.
getFieldsListWithAnnotation
(
subClass
,
Excel
.
class
);
}
}
}
// 多注解
// 多注解
...
@@ -1473,4 +1604,61 @@ public class ExcelUtil<T>
...
@@ -1473,4 +1604,61 @@ public class ExcelUtil<T>
}
}
return
str
;
return
str
;
}
}
/**
* 是否有对象的子列表
*/
public
boolean
isSubList
()
{
return
StringUtils
.
isNotNull
(
subFields
)
&&
subFields
.
size
()
>
0
;
}
/**
* 是否有对象的子列表,集合不为空
*/
public
boolean
isSubListValue
(
T
vo
)
{
return
StringUtils
.
isNotNull
(
subFields
)
&&
subFields
.
size
()
>
0
&&
StringUtils
.
isNotNull
(
getListCellValue
(
vo
))
&&
getListCellValue
(
vo
).
size
()
>
0
;
}
/**
* 获取集合的值
*/
public
Collection
<?>
getListCellValue
(
Object
obj
)
{
Object
value
;
try
{
value
=
subMethod
.
invoke
(
obj
,
new
Object
[]
{});
}
catch
(
Exception
e
)
{
return
new
ArrayList
<
Object
>();
}
return
(
Collection
<?>)
value
;
}
/**
* 获取对象的子列表方法
*
* @param name 名称
* @param pojoClass 类对象
* @return 子列表方法
*/
public
Method
getSubMethod
(
String
name
,
Class
<?>
pojoClass
)
{
StringBuffer
getMethodName
=
new
StringBuffer
(
"get"
);
getMethodName
.
append
(
name
.
substring
(
0
,
1
).
toUpperCase
());
getMethodName
.
append
(
name
.
substring
(
1
));
Method
method
=
null
;
try
{
method
=
pojoClass
.
getMethod
(
getMethodName
.
toString
(),
new
Class
[]
{});
}
catch
(
Exception
e
)
{
log
.
error
(
"获取对象异常{}"
,
e
.
getMessage
());
}
return
method
;
}
}
}
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